package dev.lions.user.manager.dto.role;

import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.enums.role.TypeRole;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

import java.io.Serializable;
import java.util.List;

/**
 * DTO pour assigner ou révoquer des rôles à un utilisateur
 * Utilisé dans les opérations d'attribution de rôles
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Attribution ou révocation de rôles")
public class RoleAssignmentDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    @NotBlank(message = "L'ID utilisateur est obligatoire")
    @Schema(description = "ID de l'utilisateur cible", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true)
    private String userId;

    @Schema(description = "Username de l'utilisateur cible (optionnel)", example = "jdupont")
    private String username;

    @NotEmpty(message = "Au moins un rôle doit être spécifié")
    @Schema(description = "Liste des noms de rôles à attribuer ou révoquer", required = true)
    private List<String> roleNames;

    @Schema(description = "Liste des IDs de rôles à attribuer ou révoquer")
    private List<String> roleIds;

    @NotNull(message = "Le type de rôle est obligatoire")
    @Schema(description = "Type de rôle", example = "REALM_ROLE", required = true)
    private TypeRole typeRole;

    @Schema(description = "Nom du Realm", example = "btpxpress")
    private String realmName;

    @Schema(description = "Nom du Client (requis si typeRole = CLIENT_ROLE)", example = "btpxpress-app")
    private String clientName;

    @Schema(description = "ID du Client (optionnel)")
    private String clientId;

    @Schema(description = "Raison de l'attribution/révocation", example = "Promotion au poste de gestionnaire")
    private String raison;

    @Schema(description = "Commentaires administratifs", example = "Demandé par le manager")
    private String commentaires;

    @Schema(description = "Indique si c'est une attribution temporaire", example = "false")
    private Boolean temporaire;

    @Schema(description = "Date d'expiration de l'attribution temporaire", example = "2025-12-31T23:59:59")
    private String dateExpiration;

    @Schema(description = "Indique si les rôles composites doivent être inclus", example = "true")
    @Builder.Default
    private Boolean includeComposites = true;

    @Schema(description = "Indique si l'opération doit notifier l'utilisateur", example = "true")
    @Builder.Default
    private Boolean notifyUser = false;

    /**
     * Valide que les données nécessaires sont présentes pour un rôle client
     * @return true si valide
     */
    public boolean isValidForClientRole() {
        return typeRole == TypeRole.CLIENT_ROLE && clientName != null && !clientName.isBlank();
    }

    /**
     * Valide que les données nécessaires sont présentes pour un rôle realm
     * @return true si valide
     */
    public boolean isValidForRealmRole() {
        return typeRole == TypeRole.REALM_ROLE;
    }

    /**
     * Retourne le nombre de rôles à assigner/révoquer
     * @return nombre de rôles
     */
    public int getRoleCount() {
        return roleNames != null ? roleNames.size() : 0;
    }
}
