package fr.titionfire.ffsaf.data.model;

import fr.titionfire.ffsaf.utils.Categorie;
import fr.titionfire.ffsaf.utils.Genre;
import fr.titionfire.ffsaf.utils.ResultPrivacy;
import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@RegisterForReflection

@Entity
@Table(name = "competition_guest")
public class CompetitionGuestModel implements CombModel {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "competition", referencedColumnName = "id")
    CompetitionModel competition;

    String lname = "";
    String fname = "";

    Categorie categorie = null;

    String club = null;

    Genre genre = null;

    String country = "fr";

    Float weight = null;
    Float weightReal = null;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    @JoinTable(
            name = "groupe_membre",
            joinColumns = @JoinColumn(name = "groupe_id"),
            inverseJoinColumns = @JoinColumn(name = "membre_id")
    )
    List<MembreModel> comb = new ArrayList<>();

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    @JoinTable(
            name = "groupe_guest",
            joinColumns = @JoinColumn(name = "groupe_id"),
            inverseJoinColumns = @JoinColumn(name = "guest_id")
    )
    List<CompetitionGuestModel> guest = new ArrayList<>();

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinTable(
            name = "categories_insc_guest",
            joinColumns = @JoinColumn(name = "guest_id"),
            inverseJoinColumns = @JoinColumn(name = "category_id")
    )
    List<CatPresetModel> categoriesInscrites = new ArrayList<>();

    public CompetitionGuestModel(String s) {
        this.fname = s.substring(0, s.indexOf(" "));
        this.lname = s.substring(s.indexOf(" ") + 1);
    }

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

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

    @Override
    public String getName(MembreModel model, ResultPrivacy privacy) {
        return getName();
    }

    public boolean isTeam() {
        return "__team".equals(this.lname);
    }

    public boolean isInTeam(Object comb_) {
        if (!this.isTeam())
            return false;

        if (comb_ instanceof Long id_) {
            if (id_ >= 0)
                return comb.stream().anyMatch(membre -> Objects.equals(membre.getId(), id_));
            else
                return guest.stream().anyMatch(guestModel -> Objects.equals(guestModel.getId(), -id_));
        }
        return Stream.concat(comb.stream(), guest.stream()).anyMatch(c -> Objects.equals(c, comb_));
    }

    public Float getWeight2() {
        return (this.weightReal != null) ? this.weightReal : this.weight;
    }
}
