package fr.titionfire.ffsaf.data.model;

import fr.titionfire.ffsaf.data.id.RegisterId;
import fr.titionfire.ffsaf.utils.Categorie;
import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@RegisterForReflection

@Entity
@Table(name = "register")
public class RegisterModel {

    @EmbeddedId
    RegisterId id;

    @MapsId("competitionId")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_competition")
    CompetitionModel competition;

    @MapsId("membreId")
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "id_membre")
    MembreModel membre;

    Float weight;
    Float weightReal;
    int overCategory = 0;
    Categorie categorie;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "club")
    @OnDelete(action = OnDeleteAction.SET_NULL)
    ClubModel club = null;

    @Column(nullable = false, columnDefinition = "boolean default false")
    boolean lockEdit = false;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinTable(
            name = "categories_insc_comb",
            joinColumns = {
                    @JoinColumn(name = "id_competition", referencedColumnName = "id_competition"),
                    @JoinColumn(name = "id_membre", referencedColumnName = "id_membre")
            },
            inverseJoinColumns = @JoinColumn(name = "category_id")
    )
    List<CatPresetModel> categoriesInscrites = new ArrayList<>();

    public RegisterModel(CompetitionModel competition, MembreModel membre, Float weight, int overCategory,
                         Categorie categorie, ClubModel club) {
        this.id = new RegisterId(competition.getId(), membre.getId());
        this.competition = competition;
        this.membre = membre;
        this.weight = weight;
        this.overCategory = overCategory;
        this.categorie = categorie;
        this.club = club;
    }

    public String getName() {
        return membre.fname + " " + membre.lname;
    }

    public ClubModel getClub2() {
        if (club == null)
            return membre.club;
        return club;
    }

    public Categorie getCategorie2() {
        Categorie tmp = this.categorie;
        if (tmp == null)
            tmp = membre.getCategorie();
        if (tmp == null)
            return null;
        return Categorie.values()[Math.min(tmp.ordinal() + this.overCategory, Categorie.values().length - 1)];
    }

    public Float getWeight2() {
        if (weightReal != null)
            return weightReal;
        return weight;
    }
}
