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

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.dto.base.BaseDTO;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import io.quarkus.runtime.annotations.RegisterForReflection;

import java.time.LocalDateTime;

/**
 * DTO pour assigner ou révoquer l'accès d'un utilisateur à un realm
 * Permet de gérer les permissions multi-tenant
 */
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Attribution ou révocation d'accès à un realm")
@RegisterForReflection
public class RealmAssignmentDTO extends BaseDTO {

    private static final long serialVersionUID = 1L;

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

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

    @Schema(description = "Email de l'utilisateur", example = "jdupont@example.com")
    private String email;

    @NotBlank(message = "Le nom du realm est obligatoire")
    @Schema(description = "Nom du realm assigné", example = "btpxpress", required = true)
    private String realmName;

    @Schema(description = "Indique si l'utilisateur est super admin (peut gérer tous les realms)", example = "false")
    private Boolean isSuperAdmin;

    @Schema(description = "Date d'assignation", example = "2025-01-15T10:30:00")
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private LocalDateTime assignedAt;

    @Schema(description = "Username de l'administrateur qui a fait l'assignation", example = "admin@lions.dev")
    private String assignedBy;

    @Schema(description = "Raison de l'assignation", example = "Nouveau gestionnaire du realm client")
    private String raison;

    @Schema(description = "Commentaires administratifs", example = "Accès temporaire pour support")
    private String commentaires;

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

    @Schema(description = "Date d'expiration de l'assignation temporaire", example = "2025-12-31T23:59:59")
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private LocalDateTime dateExpiration;

    @Schema(description = "Indique si l'assignation est active", example = "true")
    private Boolean active;

    /**
     * Vérifie si l'assignation est temporaire
     * @return true si temporaire
     */
    public boolean isTemporaire() {
        return Boolean.TRUE.equals(temporaire);
    }

    /**
     * Vérifie si l'assignation est active
     * @return true si active
     */
    public boolean isActive() {
        return Boolean.TRUE.equals(active);
    }

    /**
     * Vérifie si l'assignation a expiré
     * @return true si expirée
     */
    public boolean isExpired() {
        if (!isTemporaire() || dateExpiration == null) {
            return false;
        }
        return LocalDateTime.now().isAfter(dateExpiration);
    }

    /**
     * Vérifie si l'utilisateur est super admin
     * @return true si super admin
     */
    public boolean isSuperAdmin() {
        return Boolean.TRUE.equals(isSuperAdmin);
    }

    /**
     * Retourne un résumé de l'assignation
     * @return résumé
     */
    public String getSummary() {
        return String.format("Realm '%s' assigné à %s%s",
            realmName,
            username != null ? username : userId,
            isTemporaire() ? " (temporaire)" : ""
        );
    }
}
