
package de.ivu.elect.business.wahlvorschlag.entity;

import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static java.util.stream.Collectors.toSet;

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

import javax.annotation.Nullable;

import de.ivu.elect.business.gruppe.entity.NlPolitischeGruppeArt;

public class StelInformationen implements Serializable {

  private static final long serialVersionUID = 1L;

  private final NlPolitischeGruppeArt nlPolitischeGruppeArt;

  @Nullable
  private final Integer stelNummerAnzeige; // ELECT-11708 Trennung zwischen Sortierung und Anzeige

  @Nullable
  private final Integer stelSortierung; // ELECT-11708 Trennung zwischen Sortierung und Anzeige


  private final Set<WahlvorschlagPK> listenDesStels;

  public static StelInformationen createUnbekannt(Liste liste) {
    return new StelInformationen(NlPolitischeGruppeArt.UNBEKANNT, null, null, liste == null ? emptySet() : singleton(liste.getPk()));
  }

  public static StelInformationen createAbgelehnt(Collection<Liste> abgelehnteListenDerGruppe) {
    return new StelInformationen(NlPolitischeGruppeArt.ABGELEHNT, null,null, abgelehnteListenDerGruppe.stream().map(Wahlvorschlag::getPk).collect(toSet()));
  }

  public static StelInformationen createEinzelListe(Liste liste) {
    return new StelInformationen(NlPolitischeGruppeArt.EINZELLISTE, null,null, liste == null ? emptySet() : singleton(liste.getPk()));
  }

  public static StelInformationen createIdentischeListe(Collection<Liste> listenDesStels) {
    return new StelInformationen(NlPolitischeGruppeArt.IDENTISCHE_LISTE, 0 /* Bei identischen Listen immer Stel 0 */, 0,
        listenDesStels.stream().map(Wahlvorschlag::getPk).collect(toSet()));
  }

  public static StelInformationen createListengruppe(Integer stelNummerAnzeige, int stelSortierung, Collection<Liste> listenDesStels) {
    return new StelInformationen(NlPolitischeGruppeArt.LISTENGRUPPE, stelNummerAnzeige, stelSortierung ,
        listenDesStels.stream().map(Wahlvorschlag::getPk).collect(toSet()));
  }

  private StelInformationen(NlPolitischeGruppeArt nlPolitischeGruppeArt, @Nullable Integer stelNummerAnzeige, @Nullable Integer stelSortierung,
                            Set<WahlvorschlagPK> listenDesStels) {
    super();

    this.nlPolitischeGruppeArt = nlPolitischeGruppeArt;

    this.stelNummerAnzeige = stelNummerAnzeige;
    this.stelSortierung = stelSortierung;

    this.listenDesStels = listenDesStels;
  }

  public boolean isEinzelliste() {
    return getNlPolitischeGruppeArt().isEinzelliste();
  }

  public boolean isIdentischeListe() {
    return getNlPolitischeGruppeArt().isIdentischeListe();
  }

  public boolean isEchterStel() {
    return isListengruppe() && getListenDesStels().size() > 1;
  }

  public boolean isUnechterStel() {
    return isListengruppe() && getListenDesStels().size() < 2;
  }

  public boolean isAbgelehnterStel() {
    return isAbgelehnt() && getListenDesStels().size() > 1;
  }

  public boolean isListengruppe() {
    return getNlPolitischeGruppeArt().isListengruppe();
  }

  public boolean isAbgelehnt() {
    return getNlPolitischeGruppeArt().isAbgelehnt();
  }

  public NlPolitischeGruppeArt getNlPolitischeGruppeArt() {
    return nlPolitischeGruppeArt;
  }

  @Nullable
  public Integer getStelNummerAnzeige() {
    return stelNummerAnzeige;
  }

  @Nullable
  public Integer getStelSortierung() {
    return stelSortierung;
  }

  public Set<WahlvorschlagPK> getListenDesStels() {
    return listenDesStels;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    StelInformationen that = (StelInformationen) o;

    if (nlPolitischeGruppeArt != that.nlPolitischeGruppeArt) return false;
    if (stelNummerAnzeige != null ? !stelNummerAnzeige.equals(that.stelNummerAnzeige) : that.stelNummerAnzeige != null) return false;
    return stelSortierung != null ? stelSortierung.equals(that.stelSortierung) : that.stelSortierung == null;
  }

  @Override
  public int hashCode() {
    int result = nlPolitischeGruppeArt.hashCode();
    result = 31 * result + (stelNummerAnzeige != null ? stelNummerAnzeige.hashCode() : 0);
    result = 31 * result + (stelSortierung != null ? stelSortierung.hashCode() : 0);
    return result;
  }

  @Override
  public String toString() {
    return "StelInformationen{" +
        "nlPolitischeGruppeArt=" + nlPolitischeGruppeArt +
        ", stelNummerAnzeige=" + stelNummerAnzeige +
        ", stelSortierung=" + stelSortierung +
        ", listenDesStels=" + listenDesStels +
        '}';
  }
}
