package handlers

import (
	"net/http"
	"strconv"
	"time"

	apperrors "veza-backend-api/internal/errors"
	"veza-backend-api/internal/services"
	"veza-backend-api/internal/types"
	"veza-backend-api/internal/utils"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"go.uber.org/zap"
)

// ProfileHandler handles profile-related operations
type ProfileHandler struct {
	userService       *services.UserService
	commonHandler     *CommonHandler
	permissionService *services.PermissionService // MOD-P1-003: Added for admin check
	socialService     *services.SocialService     // BE-API-017: Added for follow/unfollow functionality
	logger            *zap.Logger                 // BE-API-017: Added for logging
}

// NewProfileHandler creates a new ProfileHandler instance
func NewProfileHandler(userService *services.UserService, logger *zap.Logger) *ProfileHandler {
	return &ProfileHandler{
		userService:   userService,
		commonHandler: NewCommonHandler(logger),
		logger:        logger,
	}
}

// SetSocialService sets the social service for follow/unfollow functionality
// BE-API-017: Implement user follow/unfollow endpoints
func (h *ProfileHandler) SetSocialService(socialService *services.SocialService) {
	h.socialService = socialService
}

// SetPermissionService définit le service de permissions (pour injection de dépendance)
// MOD-P1-003: Added for admin check in ownership verification
func (h *ProfileHandler) SetPermissionService(permissionService *services.PermissionService) {
	h.permissionService = permissionService
}

// GetProfile retrieves a public user profile by ID
// @Summary      Get Profile by ID
// @Description  Get public profile information for a user
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        id   path      string  true  "User ID"
// @Success      200  {object}  handlers.APIResponse{data=object{profile=object}}
// @Failure      400  {object}  handlers.APIResponse "Invalid ID"
// @Failure      404  {object}  handlers.APIResponse "User not found"
// @Router       /users/{id} [get]
func (h *ProfileHandler) GetProfile(c *gin.Context) {
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "invalid user id"))
		return
	}

	// Get the requesting user ID if authenticated (optional)
	var requesterID *uuid.UUID
	if reqID, exists := c.Get("user_id"); exists {
		if reqUUID, ok := reqID.(uuid.UUID); ok {
			requesterID = &reqUUID
		}
	}

	// Get user profile with privacy check
	profile, err := h.userService.GetProfile(userID, requesterID)
	if err != nil {
		RespondWithAppError(c, apperrors.New(apperrors.ErrCodeNotFound, "user not found"))
		return
	}

	RespondSuccess(c, http.StatusOK, profile)
}

// GetProfileByUsername retrieves a public profile by username
// @Summary      Get Profile by Username
// @Description  Get public profile information for a user by username
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        username path string true "Username"
// @Success      200  {object}  handlers.APIResponse{data=object{profile=object}}
// @Failure      400  {object}  handlers.APIResponse "Missing username"
// @Failure      404  {object}  handlers.APIResponse "User not found"
// @Router       /users/by-username/{username} [get]
func (h *ProfileHandler) GetProfileByUsername(c *gin.Context) {
	username := c.Param("username")
	// BE-SEC-009: Sanitize username parameter to prevent injection
	username = utils.SanitizeUsername(username)
	if username == "" {
		RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "username required"))
		return
	}

	// Get the requesting user ID if authenticated (optional)
	var requesterID *uuid.UUID
	if reqID, exists := c.Get("user_id"); exists {
		if reqUUID, ok := reqID.(uuid.UUID); ok {
			requesterID = &reqUUID
		}
	}

	// Get profile with privacy check
	profile, err := h.userService.GetProfileByUsername(username, requesterID)
	if err != nil {
		RespondWithAppError(c, apperrors.New(apperrors.ErrCodeNotFound, "user not found"))
		return
	}

	RespondSuccess(c, http.StatusOK, profile)
}

// GetProfileCompletion retrieves the profile completion status
// GET /api/v1/users/:id/completion
// BE-API-023: Implement user completion endpoint validation
// T0220: Returns percentage and missing fields
// @Summary      Get Profile Completion
// @Description  Get profile completion percentage and missing fields
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        id   path      string  true  "User ID"
// @Success      200  {object}  handlers.APIResponse{data=object}
// @Failure      400  {object}  handlers.APIResponse "Invalid ID"
// @Failure      401  {object}  handlers.APIResponse "Unauthorized"
// @Failure      403  {object}  handlers.APIResponse "Forbidden"
// @Router       /users/{id}/completion [get]
func (h *ProfileHandler) GetProfileCompletion(c *gin.Context) {
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.NewValidationError("invalid user id"))
		return
	}

	// Get authenticated user ID
	authenticatedUserID, ok := GetUserIDUUID(c)
	if !ok {
		return // Erreur déjà envoyée par GetUserIDUUID
	}

	// Verify that user_id corresponds to authenticated user
	if userID != authenticatedUserID {
		RespondWithAppError(c, apperrors.NewForbiddenError("cannot access other user's profile completion"))
		return
	}

	// Calculate profile completion
	completion, err := h.userService.CalculateProfileCompletion(userID)
	if err != nil {
		if err.Error() == "user not found" {
			RespondWithAppError(c, apperrors.NewNotFoundError("user"))
			return
		}
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "failed to calculate profile completion", err))
		return
	}

	// Verify that percentage is between 0 and 100
	if completion.Percentage < 0 || completion.Percentage > 100 {
		h.logger.Warn("Invalid completion percentage calculated",
			zap.Int("percentage", completion.Percentage),
			zap.String("user_id", userID.String()))
		// Clamp to valid range
		if completion.Percentage < 0 {
			completion.Percentage = 0
		} else if completion.Percentage > 100 {
			completion.Percentage = 100
		}
	}

	RespondSuccess(c, http.StatusOK, completion)
}

// ListUsers gère la liste des utilisateurs avec pagination et filtrage
// BE-API-040: Implement user list endpoint
// @Summary      List Users
// @Description  Get a paginated list of users with optional filtering
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        page        query     int     false  "Page number" default(1)
// @Param        limit       query     int     false  "Items per page" default(20)
// @Param        role        query     string  false  "Filter by role"
// @Param        is_active   query     bool    false  "Filter by active status"
// @Param        is_verified query     bool    false  "Filter by verified status"
// @Param        search      query     string  false  "Search by username, email, first_name, last_name"
// @Param        sort_by     query     string  false  "Sort field (created_at, username, email, last_login_at)" default(created_at)
// @Param        sort_order   query     string  false  "Sort order (asc, desc)" default(desc)
// @Success      200  {object}  handlers.APIResponse{data=object{users=array,pagination=object}}
// @Failure      500  {object}  handlers.APIResponse "Internal Error"
// @Router       /users [get]
func (h *ProfileHandler) ListUsers(c *gin.Context) {
	// Récupérer les paramètres de pagination
	pageParam := c.DefaultQuery("page", "1")
	limitParam := c.DefaultQuery("limit", "20")

	// Parser les paramètres de pagination
	page, err := strconv.Atoi(pageParam)
	if err != nil || page < 1 {
		page = 1
	}

	limit, err := strconv.Atoi(limitParam)
	if err != nil || limit < 1 {
		limit = 20
	}

	// Récupérer les paramètres de filtrage
	// BE-SEC-009: Sanitize search query to prevent injection
	searchQuery := utils.SanitizeText(c.Query("search"), 100)
	params := services.ListUsersParams{
		Page:      page,
		Limit:     limit,
		Role:      utils.SanitizeText(c.Query("role"), 50),
		Search:    searchQuery,
		SortBy:    utils.SanitizeText(c.DefaultQuery("sort_by", "created_at"), 50),
		SortOrder: utils.SanitizeText(c.DefaultQuery("sort_order", "desc"), 10),
	}

	// Parser is_active si fourni
	if isActiveStr := c.Query("is_active"); isActiveStr != "" {
		if isActive, err := strconv.ParseBool(isActiveStr); err == nil {
			params.IsActive = &isActive
		}
	}

	// Parser is_verified si fourni
	if isVerifiedStr := c.Query("is_verified"); isVerifiedStr != "" {
		if isVerified, err := strconv.ParseBool(isVerifiedStr); err == nil {
			params.IsVerified = &isVerified
		}
	}

	// Lister les utilisateurs
	users, total, err := h.userService.ListUsers(c.Request.Context(), params)
	if err != nil {
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to list users", err))
		return
	}

	// INT-007: Standardize pagination format
	pagination := BuildPaginationData(page, limit, total)

	RespondSuccess(c, http.StatusOK, gin.H{
		"users":      users,
		"pagination": pagination,
	})
}

// SearchUsers gère la recherche d'utilisateurs
// BE-API-008: Implement user search endpoint
func (h *ProfileHandler) SearchUsers(c *gin.Context) {
	// Récupérer les paramètres de recherche
	query := c.Query("q")
	pageParam := c.DefaultQuery("page", "1")
	limitParam := c.DefaultQuery("limit", "20")

	// Parser les paramètres
	page, err := strconv.Atoi(pageParam)
	if err != nil || page < 1 {
		page = 1
	}

	limit, err := strconv.Atoi(limitParam)
	if err != nil || limit < 1 {
		limit = 20
	}

	// Rechercher les utilisateurs
	users, total, err := h.userService.SearchUsers(c.Request.Context(), services.SearchUsersParams{
		Query: query,
		Page:  page,
		Limit: limit,
	})
	if err != nil {
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to search users", err))
		return
	}

	// INT-007: Standardize pagination format
	pagination := BuildPaginationData(page, limit, total)

	RespondSuccess(c, http.StatusOK, gin.H{
		"users":      users,
		"pagination": pagination,
	})
}

// FollowUser gère le suivi d'un utilisateur
// POST /api/v1/users/:id/follow
// BE-API-017: Implement user follow/unfollow endpoints
func (h *ProfileHandler) FollowUser(c *gin.Context) {
	// Récupérer l'ID de l'utilisateur à suivre depuis l'URL
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.NewValidationError("invalid user id"))
		return
	}

	// Récupérer l'ID de l'utilisateur authentifié
	followerID, ok := GetUserIDUUID(c)
	if !ok {
		return // Erreur déjà envoyée par GetUserIDUUID
	}

	// Vérifier qu'on ne peut pas se suivre soi-même
	if followerID == userID {
		RespondWithAppError(c, apperrors.NewValidationError("cannot follow yourself"))
		return
	}

	// Vérifier que l'utilisateur existe (on peut utiliser GetProfile qui vérifie l'existence)
	// Pour simplifier, on laisse le service social gérer l'erreur si l'utilisateur n'existe pas

	// Vérifier que le service social est initialisé
	if h.socialService == nil {
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Social service not initialized", nil))
		return
	}

	// Suivre l'utilisateur
	err = h.socialService.FollowUser(followerID, userID)
	if err != nil {
		h.logger.Error("failed to follow user",
			zap.Error(err),
			zap.String("follower_id", followerID.String()),
			zap.String("followed_id", userID.String()))
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to follow user", err))
		return
	}

	h.logger.Info("user followed",
		zap.String("follower_id", followerID.String()),
		zap.String("followed_id", userID.String()))

	RespondSuccess(c, http.StatusOK, gin.H{"message": "User followed successfully"})
}

// UnfollowUser gère l'arrêt du suivi d'un utilisateur
// DELETE /api/v1/users/:id/follow
// BE-API-017: Implement user follow/unfollow endpoints
func (h *ProfileHandler) UnfollowUser(c *gin.Context) {
	// Récupérer l'ID de l'utilisateur à ne plus suivre depuis l'URL
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.NewValidationError("invalid user id"))
		return
	}

	// Récupérer l'ID de l'utilisateur authentifié
	followerID, ok := GetUserIDUUID(c)
	if !ok {
		return // Erreur déjà envoyée par GetUserIDUUID
	}

	// Vérifier que le service social est initialisé
	if h.socialService == nil {
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Social service not initialized", nil))
		return
	}

	// Ne plus suivre l'utilisateur
	err = h.socialService.UnfollowUser(followerID, userID)
	if err != nil {
		h.logger.Error("failed to unfollow user",
			zap.Error(err),
			zap.String("follower_id", followerID.String()),
			zap.String("followed_id", userID.String()))
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to unfollow user", err))
		return
	}

	h.logger.Info("user unfollowed",
		zap.String("follower_id", followerID.String()),
		zap.String("followed_id", userID.String()))

	RespondSuccess(c, http.StatusOK, gin.H{"message": "User unfollowed successfully"})
}

// BlockUser gère le blocage d'un utilisateur
// POST /api/v1/users/:id/block
// BE-API-018: Implement user block/unblock endpoints
func (h *ProfileHandler) BlockUser(c *gin.Context) {
	// Récupérer l'ID de l'utilisateur à bloquer depuis l'URL
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.NewValidationError("invalid user id"))
		return
	}

	// Récupérer l'ID de l'utilisateur authentifié
	blockerID, ok := GetUserIDUUID(c)
	if !ok {
		return // Erreur déjà envoyée par GetUserIDUUID
	}

	// Vérifier qu'on ne peut pas se bloquer soi-même
	if blockerID == userID {
		RespondWithAppError(c, apperrors.NewValidationError("cannot block yourself"))
		return
	}

	// Vérifier que le service social est initialisé
	if h.socialService == nil {
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Social service not initialized", nil))
		return
	}

	// Bloquer l'utilisateur
	err = h.socialService.BlockUser(blockerID, userID)
	if err != nil {
		if err.Error() == "cannot block yourself" {
			RespondWithAppError(c, apperrors.NewValidationError("cannot block yourself"))
			return
		}
		h.logger.Error("failed to block user",
			zap.Error(err),
			zap.String("blocker_id", blockerID.String()),
			zap.String("blocked_id", userID.String()))
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to block user", err))
		return
	}

	h.logger.Info("user blocked",
		zap.String("blocker_id", blockerID.String()),
		zap.String("blocked_id", userID.String()))

	RespondSuccess(c, http.StatusOK, gin.H{"message": "User blocked successfully"})
}

// UnblockUser gère le déblocage d'un utilisateur
// DELETE /api/v1/users/:id/block
// BE-API-018: Implement user block/unblock endpoints
func (h *ProfileHandler) UnblockUser(c *gin.Context) {
	// Récupérer l'ID de l'utilisateur à débloquer depuis l'URL
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.NewValidationError("invalid user id"))
		return
	}

	// Récupérer l'ID de l'utilisateur authentifié
	blockerID, ok := GetUserIDUUID(c)
	if !ok {
		return // Erreur déjà envoyée par GetUserIDUUID
	}

	// Vérifier que le service social est initialisé
	if h.socialService == nil {
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Social service not initialized", nil))
		return
	}

	// Débloquer l'utilisateur
	err = h.socialService.UnblockUser(blockerID, userID)
	if err != nil {
		h.logger.Error("failed to unblock user",
			zap.Error(err),
			zap.String("blocker_id", blockerID.String()),
			zap.String("blocked_id", userID.String()))
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to unblock user", err))
		return
	}

	h.logger.Info("user unblocked",
		zap.String("blocker_id", blockerID.String()),
		zap.String("blocked_id", userID.String()))

	RespondSuccess(c, http.StatusOK, gin.H{"message": "User unblocked successfully"})
}

// UpdateProfileRequest represents the request body for updating a user profile
type UpdateProfileRequest struct {
	FirstName   string                 `json:"first_name" binding:"omitempty,max=100" validate:"omitempty,max=100"`
	LastName    string                 `json:"last_name" binding:"omitempty,max=100" validate:"omitempty,max=100"`
	Username    string                 `json:"username" binding:"omitempty,min=3,max=30" validate:"omitempty,min=3,max=30,username"`
	Bio         string                 `json:"bio" binding:"omitempty,max=500" validate:"omitempty,max=500"`
	Location    string                 `json:"location" binding:"omitempty,max=100" validate:"omitempty,max=100"`
	Birthdate   string                 `json:"birthdate" binding:"omitempty,datetime=2006-01-02" validate:"omitempty,datetime=2006-01-02"`
	Gender      string                 `json:"gender" binding:"omitempty,oneof=Male Female Other 'Prefer not to say'" validate:"omitempty,oneof=Male Female Other 'Prefer not to say'"`
	SocialLinks map[string]interface{} `json:"social_links" binding:"omitempty"`
}

// UpdateProfile updates a user profile
// @Summary      Update Profile
// @Description  Update user profile details
// @Tags         User
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Param        id      path      string                true  "User ID"
// @Param        profile body      UpdateProfileRequest  true  "Profile Data"
// @Success      200     {object}  handlers.APIResponse{data=object{profile=object}}
// @Failure      400     {object}  handlers.APIResponse "Validation Error"
// @Failure      401     {object}  handlers.APIResponse "Unauthorized"
// @Failure      403     {object}  handlers.APIResponse "Forbidden"
// @Router       /users/{id} [put]
func (h *ProfileHandler) UpdateProfile(c *gin.Context) {
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "invalid user id"))
		return
	}

	// Get authenticated user ID
	var authenticatedUserID uuid.UUID
	if reqID, exists := c.Get("user_id"); exists {
		if reqUUID, ok := reqID.(uuid.UUID); ok {
			authenticatedUserID = reqUUID
		} else {
			RespondWithAppError(c, apperrors.NewUnauthorizedError("user not authenticated"))
			return
		}
	} else {
		RespondWithAppError(c, apperrors.NewUnauthorizedError("user not authenticated"))
		return
	}

	// MOD-P1-003: Verify that user_id corresponds to authenticated user or user is admin
	isAdmin := false
	if h.permissionService != nil {
		hasRole, err := h.permissionService.HasRole(c.Request.Context(), authenticatedUserID, "admin")
		if err == nil && hasRole {
			isAdmin = true
		}
	}

	if userID != authenticatedUserID && !isAdmin {
		RespondWithAppError(c, apperrors.NewForbiddenError("cannot update other user's profile"))
		return
	}

	var req UpdateProfileRequest
	if appErr := h.commonHandler.BindAndValidateJSON(c, &req); appErr != nil {
		RespondWithAppError(c, appErr)
		return
	}

	// BE-SEC-009: Sanitize user inputs to prevent XSS and injection attacks
	if req.Username != "" {
		req.Username = utils.SanitizeUsername(req.Username)
	}
	if req.Bio != "" {
		req.Bio = utils.SanitizeText(req.Bio, 500)
	}
	if req.FirstName != "" {
		req.FirstName = utils.SanitizeText(req.FirstName, 100)
	}
	if req.LastName != "" {
		req.LastName = utils.SanitizeText(req.LastName, 100)
	}

	// Validate username if provided
	if req.Username != "" {
		// Validate username format (alphanumeric + underscore, 3-30 chars)
		if !isValidUsername(req.Username) {
			RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "username must be 3-30 characters, alphanumeric and underscore only"))
			return
		}

		// Validate username uniqueness if modified
		if err := h.userService.ValidateUsername(userID, req.Username); err != nil {
			RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, err.Error()))
			return
		}

		// Check if username can be modified (once per month)
		canChange, err := h.userService.CanChangeUsername(userID)
		if err != nil {
			RespondWithAppError(c, apperrors.New(apperrors.ErrCodeInternal, "failed to check username change eligibility"))
			return
		}
		if !canChange {
			RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "username can only be changed once per month"))
			return
		}
	}

	// Validate birthdate if provided
	if req.Birthdate != "" {
		birthdate, err := time.Parse("2006-01-02", req.Birthdate)
		if err != nil {
			RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "invalid birthdate format, expected YYYY-MM-DD"))
			return
		}

		// Check if user is at least 13 years old
		age := time.Since(birthdate)
		minAge := 13 * 365 * 24 * time.Hour // 13 years
		if age < minAge {
			RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "user must be at least 13 years old"))
			return
		}
	}

	// Convert UpdateProfileRequest to types.UpdateProfileRequest
	serviceReq := types.UpdateProfileRequest{
		FirstName:   &req.FirstName,
		LastName:    &req.LastName,
		Username:    &req.Username,
		Bio:         &req.Bio,
		Location:    &req.Location,
		Gender:      &req.Gender,
		SocialLinks: req.SocialLinks,
	}

	if req.Birthdate != "" {
		birthdate, _ := time.Parse("2006-01-02", req.Birthdate)
		birthdateStr := birthdate.Format("2006-01-02")
		serviceReq.BirthDate = &birthdateStr
	}

	// Update profile using the new UpdateProfile method
	profile, err := h.userService.UpdateProfile(userID, serviceReq)
	if err != nil {
		RespondWithAppError(c, apperrors.New(apperrors.ErrCodeInternal, "failed to update profile"))
		return
	}

	RespondSuccess(c, http.StatusOK, profile)
}

// isValidUsername validates username format (alphanumeric + underscore, 3-30 chars)
func isValidUsername(username string) bool {
	if len(username) < 3 || len(username) > 30 {
		return false
	}

	for _, char := range username {
		if !((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') || char == '_') {
			return false
		}
	}

	return true
}

// DeleteUser gère la suppression d'un utilisateur (soft delete)
// BE-API-041: DELETE /api/v1/users/:id with soft delete support
// @Summary Delete user
// @Description Soft delete a user (only user owner or admin can delete)
// @Tags User
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "User ID"
// @Success 200 {object} handlers.APIResponse "User deleted successfully"
// @Failure 400 {object} handlers.APIResponse "Invalid ID"
// @Failure 401 {object} handlers.APIResponse "Unauthorized"
// @Failure 403 {object} handlers.APIResponse "Forbidden - Not user owner or admin"
// @Failure 404 {object} handlers.APIResponse "User not found"
// @Router /users/{id} [delete]
func (h *ProfileHandler) DeleteUser(c *gin.Context) {
	userIDStr := c.Param("id")
	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		RespondWithAppError(c, apperrors.New(apperrors.ErrCodeValidation, "invalid user id"))
		return
	}

	// Get the requesting user ID
	requesterID, ok := GetUserIDUUID(c)
	if !ok {
		return // Erreur déjà envoyée par GetUserIDUUID
	}

	// Check if requester is the user owner or admin
	if requesterID != userID {
		// Check if requester is admin
		if h.permissionService != nil {
			isAdmin, err := h.permissionService.HasRole(c.Request.Context(), requesterID, "admin")
			if err != nil || !isAdmin {
				RespondWithAppError(c, apperrors.NewForbiddenError("only user owner or admin can delete user"))
				return
			}
		} else {
			RespondWithAppError(c, apperrors.NewForbiddenError("only user owner or admin can delete user"))
			return
		}
	}

	// Delete user (soft delete)
	if err := h.userService.DeleteUser(c.Request.Context(), userID); err != nil {
		if err.Error() == "user not found" {
			RespondWithAppError(c, apperrors.NewNotFoundError("user"))
			return
		}
		RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "failed to delete user", err))
		return
	}

	RespondSuccess(c, http.StatusOK, gin.H{"message": "user deleted successfully"})
}
