package fr.titionfire.ffsaf.data.model;

import fr.titionfire.ffsaf.utils.CompetitionSystem;
import fr.titionfire.ffsaf.utils.ResultPrivacy;
import fr.titionfire.ffsaf.utils.ScoreEmbeddable;
import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.persistence.*;
import lombok.*;

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

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@RegisterForReflection

@Entity
@ToString
@Table(name = "match")
public class MatchModel {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @Column(name = "system_type")
    CompetitionSystem system;
    Long systemId;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "c1", referencedColumnName = "id")
    MembreModel c1_id = null;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "c1_guest", referencedColumnName = "id")
    CompetitionGuestModel c1_guest = null;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "c2", referencedColumnName = "id")
    MembreModel c2_id = null;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "c2_guest", referencedColumnName = "id")
    CompetitionGuestModel c2_guest = null;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "id_category", referencedColumnName = "id")
    CategoryModel category = null;

    long category_ord = 0;

    boolean isEnd = true;

    Date date = null;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "score", joinColumns = @JoinColumn(name = "id_match"))
    List<ScoreEmbeddable> scores = new ArrayList<>();

    char poule = 'A';

    public String getC1Name(MembreModel model, ResultPrivacy privacy) {
        if (c1_id != null)
            return c1_id.getName(model, privacy);
        if (c1_guest != null)
            return c1_guest.getName(model, privacy);
        return "";
    }

    public String getC2Name(MembreModel model, ResultPrivacy privacy) {
        if (c2_id != null)
            return c2_id.getName(model, privacy);
        if (c2_guest != null)
            return c2_guest.getName(model, privacy);
        return "";
    }

    public String getC1Name() {
        if (c1_id != null)
            return c1_id.getName();
        if (c1_guest != null)
            return c1_guest.getName();
        return "";
    }

    public String getC2Name() {
        if (c2_id != null)
            return c2_id.getName();
        if (c2_guest != null)
            return c2_guest.getName();
        return "";
    }

    public int win() {
        int sum = 0;
        for (ScoreEmbeddable score : this.getScores()) {
            if (score.getS1() == -1000 || score.getS2() == -1000)
                continue;

            if (score.getS1() > score.getS2())
                sum++;
            else if (score.getS1() < score.getS2())
                sum--;
        }
        return sum;
    }

    public CombModel getC1() {
        if (this.c1_id != null)
            return this.c1_id;
        if (this.c1_guest != null)
            return this.c1_guest;
        return null;
    }

    public CombModel getC2() {
        if (this.c2_id != null)
            return this.c2_id;
        if (this.c2_guest != null)
            return this.c2_guest;
        return null;
    }

    public boolean isC1(Object comb) {
        if (this.c1_guest != null && this.c1_guest.isInTeam(comb))
            return true;

        if (comb instanceof Long id_) {
            if (id_ >= 0)
                return Objects.equals(this.c1_id != null ? this.c1_id.getId() : null, id_);
            else
                return Objects.equals(this.c1_guest != null ? this.c1_guest.getId() : null, -id_);
        }
        return Objects.equals(this.c1_id, comb) || Objects.equals(this.c1_guest, comb);
    }

    public boolean isC2(Object comb) {
        if (this.c2_guest != null && this.c2_guest.isInTeam(comb))
            return true;

        if (comb instanceof Long id_) {
            if (id_ >= 0)
                return Objects.equals(this.c2_id != null ? this.c2_id.getId() : null, id_);
            else
                return Objects.equals(this.c2_guest != null ? this.c2_guest.getId() : null, -id_);
        }
        return Objects.equals(this.c2_id, comb) || Objects.equals(this.c2_guest, comb);
    }
}
