package fr.titionfire.ffsaf.data.model;

import fr.titionfire.ffsaf.utils.*;
import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.persistence.*;
import lombok.*;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@RegisterForReflection

@Entity
@Table(name = "membre")
public class MembreModel implements LoggableModel, CombModel {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Access(AccessType.PROPERTY)
    @Schema(description = "L'identifiant du membre.", examples = "1")
    Long id;

    @Schema(description = "L'identifiant long du membre (userID).", examples = "e81d1d35-d897-421e-8086-6c5e74d13c6e")
    String userId;

    @Schema(description = "Le nom du membre.", examples = "Dupont")
    String lname;
    @Schema(description = "Le prénom du membre.", examples = "Jean")
    String fname;

    @Schema(description = "La catégorie du membre.", examples = "SENIOR")
    Categorie categorie;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "club", referencedColumnName = "id")
    @Schema(description = "Le club du membre.")
    ClubModel club;

    @Schema(description = "Le genre du membre.", examples = "H")
    Genre genre;

    @Schema(description = "Le numéro de licence du membre.", examples = "12345")
    Integer licence;

    @Schema(description = "Le pays du membre.", examples = "FR")
    String country;

    @Schema(description = "La date de naissance du membre.")
    Date birth_date;

    @Schema(description = "L'adresse e-mail du membre.", examples = "jean.dupont@examples.com")
    String email;

    @Schema(description = "Le rôle du membre dans l'association.", examples = "MEMBRE")
    RoleAsso role;

    @Schema(description = "Le grade d'arbitrage du membre.", examples = "NA")
    GradeArbitrage grade_arbitrage;

    @Schema(description = "La confidentialité de ces résultats", examples = "PUBLIC")
    @Column(nullable = false, columnDefinition = "smallint default 0")
    ResultPrivacy resultPrivacy = ResultPrivacy.PUBLIC;

    @OneToMany(mappedBy = "membre", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @Schema(description = "Les licences du membre. (optionnel)")
    List<LicenceModel> licences;

    @OneToMany(mappedBy = "membre", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @Schema(description = "Les séléctions du membre. (optionnel)")
    List<SelectionModel> selections;

    @Override
    public String getObjectName() {
        return fname + " " + lname;
    }

    @Override
    public LogModel.ObjectType getObjectType() {
        return LogModel.ObjectType.Membre;
    }

    @Override
    public String toString() {
        return "MembreModel{" +
                "id=" + id +
                ", userId='" + userId + '\'' +
                ", lname='" + lname + '\'' +
                ", fname='" + fname + '\'' +
                ", categorie=" + categorie +
                ", genre=" + genre +
                ", licence=" + licence +
                ", country='" + country + '\'' +
                ", birth_date=" + birth_date +
                ", email='" + email + '\'' +
                ", role=" + role +
                ", grade_arbitrage=" + grade_arbitrage +
                '}';
    }

    @Override
    public Long getCombId() {
        return this.id;
    }

    @Override
    public String getName() {
        return this.fname + " " + this.lname;
    }

    @Override
    public String getName(MembreModel model, ResultPrivacy privacy) {
        if (model == null || !Objects.equals(this.getId(), model.getId())) {
            if (model == null && this.getResultPrivacy() != ResultPrivacy.PUBLIC)
                return "Anonyme";
            if (this.getResultPrivacy().ordinal() > privacy.ordinal())
                return "Anonyme";
        }
        return getName();
    }
}
