package dev.lions.unionflow.client.dto;

import dev.lions.unionflow.client.validation.ValidPhoneNumber;
import dev.lions.unionflow.client.validation.ValidMemberNumber;
import dev.lions.unionflow.client.validation.ValidationGroups;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.UUID;

public class MembreDTO implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private UUID id;
    
    @NotBlank(message = "Le numéro de membre est obligatoire", groups = {ValidationGroups.CreateMember.class, ValidationGroups.FullRegistration.class})
    @ValidMemberNumber(groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.FullRegistration.class})
    private String numeroMembre;
    
    @NotBlank(message = "Le nom est obligatoire", groups = {ValidationGroups.CreateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    @Size(min = 2, max = 50, message = "Le nom doit contenir entre 2 et 50 caractères", groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    @Pattern(regexp = "^[a-zA-ZÀ-ÿ\\s\\-']+$", message = "Le nom ne peut contenir que des lettres, espaces, tirets et apostrophes", groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    private String nom;
    
    @NotBlank(message = "Le prénom est obligatoire", groups = {ValidationGroups.CreateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    @Size(min = 2, max = 50, message = "Le prénom doit contenir entre 2 et 50 caractères", groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    @Pattern(regexp = "^[a-zA-ZÀ-ÿ\\s\\-']+$", message = "Le prénom ne peut contenir que des lettres, espaces, tirets et apostrophes", groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    private String prenom;
    
    @Email(message = "Format d'email invalide", groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    @Size(max = 100, message = "L'email ne peut pas dépasser 100 caractères", groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.QuickRegistration.class, ValidationGroups.FullRegistration.class})
    private String email;
    
    @ValidPhoneNumber
    private String telephone;
    
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Past(message = "La date de naissance doit être dans le passé")
    private LocalDate dateNaissance;
    
    @Size(max = 200, message = "L'adresse ne peut pas dépasser 200 caractères")
    private String adresse;
    
    @Size(max = 100, message = "La profession ne peut pas dépasser 100 caractères")
    private String profession;
    
    @Size(max = 20, message = "Le statut matrimonial ne peut pas dépasser 20 caractères")
    private String statutMatrimonial;
    
    @Size(max = 50, message = "La nationalité ne peut pas dépasser 50 caractères")
    private String nationalite;
    
    @Size(max = 50, message = "Le numéro d'identité ne peut pas dépasser 50 caractères")
    private String numeroIdentite;
    
    @Size(max = 20, message = "Le type d'identité ne peut pas dépasser 20 caractères")
    private String typeIdentite;
    
    @Size(max = 255, message = "L'URL de la photo ne peut pas dépasser 255 caractères")
    private String photoUrl;
    
    @NotNull(message = "Le statut est obligatoire")
    private String statut;
    
    @NotNull(message = "L'association est obligatoire")
    private UUID associationId;
    
    private String associationNom;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime dateInscription;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime dateDerniereModification;
    
    private String creePar;
    private String modifiePar;
    
    private Boolean membreBureau = false;
    private Boolean responsable = false;
    
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate dateAdhesion;
    
    @Size(max = 50, message = "La région ne peut pas dépasser 50 caractères")
    private String region;
    
    @Size(max = 50, message = "La ville ne peut pas dépasser 50 caractères")
    private String ville;
    
    @Size(max = 50, message = "Le quartier ne peut pas dépasser 50 caractères")
    private String quartier;
    
    @Size(max = 50, message = "Le rôle ne peut pas dépasser 50 caractères")
    private String role;
    
    // Constructeurs
    public MembreDTO() {}
    
    public MembreDTO(String numeroMembre, String nom, String prenom, String email) {
        this.numeroMembre = numeroMembre;
        this.nom = nom;
        this.prenom = prenom;
        this.email = email;
        this.statut = "ACTIF";
        this.dateInscription = LocalDateTime.now();
    }
    
    // Getters et Setters
    public UUID getId() { return id; }
    public void setId(UUID id) { this.id = id; }
    
    public String getNumeroMembre() { return numeroMembre; }
    public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; }
    
    public String getNom() { return nom; }
    public void setNom(String nom) { this.nom = nom; }
    
    public String getPrenom() { return prenom; }
    public void setPrenom(String prenom) { this.prenom = prenom; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    public String getTelephone() { return telephone; }
    public void setTelephone(String telephone) { this.telephone = telephone; }
    
    public LocalDate getDateNaissance() { return dateNaissance; }
    public void setDateNaissance(LocalDate dateNaissance) { this.dateNaissance = dateNaissance; }
    
    public String getAdresse() { return adresse; }
    public void setAdresse(String adresse) { this.adresse = adresse; }
    
    public String getProfession() { return profession; }
    public void setProfession(String profession) { this.profession = profession; }
    
    public String getStatutMatrimonial() { return statutMatrimonial; }
    public void setStatutMatrimonial(String statutMatrimonial) { this.statutMatrimonial = statutMatrimonial; }
    
    public String getNationalite() { return nationalite; }
    public void setNationalite(String nationalite) { this.nationalite = nationalite; }
    
    public String getNumeroIdentite() { return numeroIdentite; }
    public void setNumeroIdentite(String numeroIdentite) { this.numeroIdentite = numeroIdentite; }
    
    public String getTypeIdentite() { return typeIdentite; }
    public void setTypeIdentite(String typeIdentite) { this.typeIdentite = typeIdentite; }
    
    public String getStatut() { return statut; }
    public void setStatut(String statut) { this.statut = statut; }
    
    public UUID getAssociationId() { return associationId; }
    public void setAssociationId(UUID associationId) { this.associationId = associationId; }
    
    public String getAssociationNom() { return associationNom; }
    public void setAssociationNom(String associationNom) { this.associationNom = associationNom; }
    
    public LocalDateTime getDateInscription() { return dateInscription; }
    public void setDateInscription(LocalDateTime dateInscription) { this.dateInscription = dateInscription; }
    
    public LocalDateTime getDateDerniereModification() { return dateDerniereModification; }
    public void setDateDerniereModification(LocalDateTime dateDerniereModification) { this.dateDerniereModification = dateDerniereModification; }
    
    public String getCreePar() { return creePar; }
    public void setCreePar(String creePar) { this.creePar = creePar; }
    
    public String getModifiePar() { return modifiePar; }
    public void setModifiePar(String modifiePar) { this.modifiePar = modifiePar; }
    
    public String getPhotoUrl() { return photoUrl; }
    public void setPhotoUrl(String photoUrl) { this.photoUrl = photoUrl; }
    
    public Boolean getMembreBureau() { return membreBureau; }
    public void setMembreBureau(Boolean membreBureau) { this.membreBureau = membreBureau; }
    
    public Boolean getResponsable() { return responsable; }
    public void setResponsable(Boolean responsable) { this.responsable = responsable; }
    
    public LocalDate getDateAdhesion() { return dateAdhesion; }
    public void setDateAdhesion(LocalDate dateAdhesion) { this.dateAdhesion = dateAdhesion; }
    
    public String getRegion() { return region; }
    public void setRegion(String region) { this.region = region; }
    
    public String getVille() { return ville; }
    public void setVille(String ville) { this.ville = ville; }
    
    public String getQuartier() { return quartier; }
    public void setQuartier(String quartier) { this.quartier = quartier; }
    
    public String getRole() { return role; }
    public void setRole(String role) { this.role = role; }
    
    // Propriétés dérivées
    public String getNomComplet() {
        return (prenom != null ? prenom : "") + " " + (nom != null ? nom : "");
    }
    
    public String getInitiales() {
        StringBuilder initiales = new StringBuilder();
        if (prenom != null && !prenom.isEmpty()) {
            initiales.append(prenom.charAt(0));
        }
        if (nom != null && !nom.isEmpty()) {
            initiales.append(nom.charAt(0));
        }
        return initiales.toString().toUpperCase();
    }
    
    public String getStatutLibelle() {
        return switch (statut != null ? statut : "") {
            case "ACTIF" -> "Actif";
            case "INACTIF" -> "Inactif";
            case "SUSPENDU" -> "Suspendu";
            case "RADIE" -> "Radié";
            default -> statut;
        };
    }
    
    public String getStatutSeverity() {
        return switch (statut != null ? statut : "") {
            case "ACTIF" -> "success";
            case "INACTIF" -> "warning";
            case "SUSPENDU" -> "danger";
            case "RADIE" -> "secondary";
            default -> "info";
        };
    }
    
    public String getStatutIcon() {
        return switch (statut != null ? statut : "") {
            case "ACTIF" -> "pi-check";
            case "INACTIF" -> "pi-times";
            case "SUSPENDU" -> "pi-ban";
            case "RADIE" -> "pi-trash";
            default -> "pi-question";
        };
    }
    
    // Propriétés pour le type de membre (à adapter selon votre logique métier)
    public String getTypeMembre() {
        // Retourne le type basé sur les rôles
        if (Boolean.TRUE.equals(responsable)) return "Responsable";
        if (Boolean.TRUE.equals(membreBureau)) return "Bureau";
        return "Membre";
    }
    
    public String getTypeSeverity() {
        if (Boolean.TRUE.equals(responsable)) return "danger";
        if (Boolean.TRUE.equals(membreBureau)) return "warning";
        return "info";
    }
    
    public String getTypeIcon() {
        if (Boolean.TRUE.equals(responsable)) return "pi-star-fill";
        if (Boolean.TRUE.equals(membreBureau)) return "pi-briefcase";
        return "pi-user";
    }
    
    // Propriétés pour l'entité (association)
    public String getEntite() {
        return associationNom != null ? associationNom : "Non renseigné";
    }
    
    // Propriétés pour l'ancienneté
    public String getAnciennete() {
        if (dateInscription == null) return "N/A";
        long jours = java.time.temporal.ChronoUnit.DAYS.between(dateInscription.toLocalDate(), LocalDate.now());
        if (jours < 30) return jours + " jours";
        if (jours < 365) return (jours / 30) + " mois";
        return (jours / 365) + " ans";
    }
    
    // Propriétés pour les cotisations (valeurs par défaut - à remplacer par vraies données)
    public String getCotisationStatut() {
        return "À jour"; // TODO: Calculer depuis les vraies cotisations
    }
    
    public String getCotisationColor() {
        return "text-green-500"; // TODO: Calculer selon le statut réel
    }
    
    public String getDernierPaiement() {
        return "Nov 2025"; // TODO: Récupérer la vraie date
    }
    
    // Propriétés pour la participation aux événements (valeurs par défaut - à remplacer)
    public String getTauxParticipation() {
        return "75"; // TODO: Calculer le vrai taux
    }
    
    public String getEvenementsAnnee() {
        return "12"; // TODO: Compter les vrais événements
    }
    
    @Override
    public String toString() {
        return "MembreDTO{" +
                "id=" + id +
                ", numeroMembre='" + numeroMembre + '\'' +
                ", nom='" + nom + '\'' +
                ", prenom='" + prenom + '\'' +
                ", email='" + email + '\'' +
                ", statut='" + statut + '\'' +
                '}';
    }
}