package de.accso.flexinale.data.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import de.accso.flexinale.shared_kernel.Identifiable;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.io.Serializable;

@jakarta.persistence.Entity
public class KinoSaal implements Identifiable, Serializable {
    @jakarta.persistence.Id
    public String id;  // primary key

    @jakarta.persistence.Column
    public String name;

    @jakarta.persistence.Column
    public Integer anzahlPlaetze = 0;

    @jakarta.persistence.ManyToOne
    @jakarta.persistence.JoinColumn(name = "kino", nullable = false)
    @JsonIgnore
    public Kino kino; //TODO bidirectional relation K<->KS. We might want to get rid of the bi-directional relationship between Kino<->KinoSaal (everywhere in M/M1/M2/D, in entities, TOs, perhaps leave them in domain classes. This bidirectional stuff made/makes problems everywhere (in equals, hashCode, mapper code, in de/serialization)
    // note that de/serialization for TO classes in Distributed does not work correctly, see commented out assert in de.accso.flexinale.backoffice.api_contract.event.EventSerializationTest

    protected KinoSaal() {
    }

    public KinoSaal(final String id) {
        this.id = id;
    }

    public KinoSaal(final String id, final String name, final Integer anzahlPlaetze, final Kino kino) {
        this.id = id;
        this.name = name;
        this.anzahlPlaetze = anzahlPlaetze;
        this.kino = kino;
    }

    @Override
    public Id id() {
        return Identifiable.Id.of(id);
    }

    @Override
    public String toString() {
        return "KinoSaal{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", anzahlPlaetze=" + anzahlPlaetze +
                (kino != null ? ", kino.id=" + kino.id : ", kino=null") +
                '}';
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {return true;}

        if (o == null || getClass() != o.getClass()) {return false;}
        KinoSaal that = (KinoSaal) o;

        EqualsBuilder builder = new EqualsBuilder().append(id, that.id).append(name, that.name)
                .append(anzahlPlaetze, that.anzahlPlaetze);
        if (kino != null) {
            builder.append(kino.id, that.kino.id); // do not check kino but only its id (otherwise Stackoverflow error)
        }
        return builder.isEquals();
    }

    @Override
    public int hashCode() {
        HashCodeBuilder builder = new HashCodeBuilder(17, 37).append(id)
                .append(name).append(anzahlPlaetze);
        if (kino != null) {
            builder.append(kino.id); // do not check kino but only its id (otherwise Stackoverflow error)
        }
        return builder.toHashCode();
    }
}
