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

import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.enums.user.StatutUser;
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.time.LocalDateTime;
import java.util.List;

/**
 * Critères de recherche pour les utilisateurs
 * Utilisé pour filtrer les utilisateurs via l'API Keycloak Admin
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Critères de recherche d'utilisateurs")
public class UserSearchCriteriaDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    // Recherche textuelle
    @Schema(description = "Terme de recherche générale (username, email, nom, prénom)", example = "dupont")
    private String searchTerm;

    @Schema(description = "Nom d'utilisateur exact", example = "jdupont")
    private String username;

    @Schema(description = "Email exact", example = "jean.dupont@lions.dev")
    private String email;

    @Schema(description = "Prénom", example = "Jean")
    private String prenom;

    @Schema(description = "Nom de famille", example = "Dupont")
    private String nom;

    @Schema(description = "Numéro de téléphone", example = "+225 01 02 03 04 05")
    private String telephone;

    // Filtres de statut
    @Schema(description = "Statut de l'utilisateur", example = "ACTIF")
    private StatutUser statut;

    @Schema(description = "Compte activé", example = "true")
    private Boolean enabled;

    @Schema(description = "Email vérifié", example = "true")
    private Boolean emailVerified;

    // Filtres de rôle et groupe
    @Schema(description = "Liste des rôles Realm à filtrer")
    private List<String> realmRoles;

    @Schema(description = "Liste des rôles Client à filtrer")
    private List<String> clientRoles;

    @Schema(description = "Liste des groupes à filtrer")
    private List<String> groups;

    @Schema(description = "Nom du client pour filtrer par rôles client", example = "btpxpress-app")
    private String clientName;

    // Filtres organisationnels
    @Schema(description = "Organisation/Entreprise", example = "Lions Dev")
    private String organisation;

    @Schema(description = "Département", example = "IT")
    private String departement;

    @Schema(description = "Fonction/Poste", example = "Développeur")
    private String fonction;

    @Schema(description = "Pays", example = "Côte d'Ivoire")
    private String pays;

    @Schema(description = "Ville", example = "Abidjan")
    private String ville;

    // Filtres temporels
    @Schema(description = "Date de création minimum", example = "2025-01-01T00:00:00")
    private LocalDateTime dateCreationMin;

    @Schema(description = "Date de création maximum", example = "2025-12-31T23:59:59")
    private LocalDateTime dateCreationMax;

    @Schema(description = "Date de dernière connexion minimum", example = "2025-01-01T00:00:00")
    private LocalDateTime derniereConnexionMin;

    @Schema(description = "Date de dernière connexion maximum", example = "2025-01-31T23:59:59")
    private LocalDateTime derniereConnexionMax;

    // Filtres spéciaux
    @Schema(description = "Utilisateurs avec actions requises uniquement", example = "true")
    private Boolean hasRequiredActions;

    @Schema(description = "Utilisateurs verrouillés uniquement", example = "false")
    private Boolean isLocked;

    @Schema(description = "Utilisateurs expirés uniquement", example = "false")
    private Boolean isExpired;

    @Schema(description = "Utilisateurs avec sessions actives uniquement", example = "true")
    private Boolean hasActiveSessions;

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

    // Pagination
    @Schema(description = "Numéro de page (commence à 0)", example = "0", defaultValue = "0")
    @Builder.Default
    private Integer page = 0;

    @Schema(description = "Taille de la page", example = "20", defaultValue = "20")
    @Builder.Default
    private Integer pageSize = 20;

    @Schema(description = "Nombre maximum de résultats", example = "100")
    private Integer maxResults;

    // Tri
    @Schema(description = "Champ de tri (username, email, prenom, nom, dateCreation, derniereConnexion)", example = "username")
    @Builder.Default
    private String sortBy = "username";

    @Schema(description = "Ordre de tri (ASC ou DESC)", example = "ASC")
    @Builder.Default
    private String sortOrder = "ASC";

    // Options d'inclusion
    @Schema(description = "Inclure les rôles dans les résultats", example = "true")
    @Builder.Default
    private Boolean includeRoles = false;

    @Schema(description = "Inclure les groupes dans les résultats", example = "true")
    @Builder.Default
    private Boolean includeGroups = false;

    @Schema(description = "Inclure les attributs personnalisés", example = "false")
    @Builder.Default
    private Boolean includeAttributes = false;

    @Schema(description = "Inclure les informations de session", example = "false")
    @Builder.Default
    private Boolean includeSessionInfo = false;

    /**
     * Détermine si des filtres de recherche sont appliqués
     * @return true si au moins un filtre est défini
     */
    public boolean hasFilters() {
        return searchTerm != null
            || username != null
            || email != null
            || prenom != null
            || nom != null
            || statut != null
            || enabled != null
            || emailVerified != null
            || (realmRoles != null && !realmRoles.isEmpty())
            || (clientRoles != null && !clientRoles.isEmpty())
            || (groups != null && !groups.isEmpty())
            || organisation != null
            || departement != null
            || fonction != null
            || pays != null
            || ville != null
            || dateCreationMin != null
            || dateCreationMax != null
            || derniereConnexionMin != null
            || derniereConnexionMax != null
            || hasRequiredActions != null
            || isLocked != null
            || isExpired != null
            || hasActiveSessions != null;
    }

    /**
     * Calcule l'offset pour la pagination Keycloak
     * @return offset calculé à partir de page et pageSize
     */
    public int getOffset() {
        return page * pageSize;
    }
}
