package de.accso.flexinale.backoffice_api_contract.api_contract.model;

import de.accso.flexinale.common.shared_kernel.*;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.io.Serializable;

public record KinoSaalTO(Id id, Version version,
                         Name name, AnzahlPlaetze anzahlPlaetze,
                         @DoNotCheckInArchitectureTests KinoTO kino)
        implements Identifiable, Versionable, EqualsByContent, Serializable
{
    public record Name(String raw) implements RawWrapper<String> {}
    public record AnzahlPlaetze(Integer raw) implements RawWrapper<Integer> {}

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

    @Override
    public boolean equals(final Object o) { // though KinoSaalTO is a record, this method is needed
                                            // (as otherwise stackoverflow error because of the bidirectional
                                            // relationship with KinoTO
        if (!equalsByContent(o)) return false;

        if (this == o) {return true;}
        if (o == null || getClass() != o.getClass()) {return false;}
        KinoSaalTO that = (KinoSaalTO) o;
        return new EqualsBuilder().append(version, that.version).isEquals();
    }

    @Override
    public int hashCode() {  // though KinoSaalTO is a record, this method is needed
                             // (as otherwise stackoverflow error because of the bidirectional
                             // relationship with KinoTO
        HashCodeBuilder builder = new HashCodeBuilder(17, 37).append(id).append(version)
                .append(name).append(anzahlPlaetze);
        if (kino != null) {
            builder.append(kino.id()); // do not use kino but only its id (otherwise Stackoverflow error)
        }
        return builder.toHashCode();
    }

    @SuppressWarnings("ConstantValue")
    @Override
    public boolean equalsByContent(final Object o) {
        if (this == o) {return true;}

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

        KinoSaalTO that = (KinoSaalTO) o;

        boolean result = new EqualsBuilder()
                .append(id, that.id)
                .append(name, that.name)
                .append(anzahlPlaetze, that.anzahlPlaetze).
                isEquals();
        if (!result) return false;

        if (kino == null && that.kino == null) return true;
        if (kino == null && that.kino != null) return false;
        if (kino != null) {
            result = kino.id().equals(that.kino.id()); // do not check kino but only its id (otherwise Stackoverflow error)
        }

        return result;
    }
}
