
package de.ivu.elect.business.stimmeingabe.control.plausi;

import static java.util.stream.Collectors.toList;

import java.util.Collection;
import java.util.Objects;

import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabe;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiKonfiguration;
import de.ivu.elect.jee.faces.Messages;

public abstract class AbstractNlStimmzettelEingenommenGesamtAnzahlComparedToWaehlerGesamtAnzahlPlausi extends AbstractStimmeingabeAnzahlComparedToStimmeingabeAnzahlenSummePlausi {

  private final Stimmeingabe stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenig;

  private final boolean stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenigHavingAnzahlGroesserNull;

  private final Stimmeingabe stimmzetteleingabeStimmzettelEingenommenAbweichendZuviel;

  private final boolean stimmzetteleingabeStimmzettelEingenommenAbweichendZuvielHavingAnzahlGroesserNull;

  private final Collection<Stimmeingabe> stimmzetteleingabenStimmzettelEingenommenAbweichendGrund;

  private final boolean stimmzetteleingabenStimmzettelEingenommenAbweichendGrundHavingAnzahlGroesserNull;

  protected AbstractNlStimmzettelEingenommenGesamtAnzahlComparedToWaehlerGesamtAnzahlPlausi(StimmeingabeAnzahlComparedToOperator comparedToOperator,
      Collection<Stimmeingabe> stimmeingabenWaehlerGesamt, Stimmeingabe stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenig,
      Stimmeingabe stimmzetteleingabeStimmzettelEingenommenAbweichendZuviel, Collection<Stimmeingabe> stimmzetteleingabenStimmzettelEingenommenAbweichendGrund,
      StimmeingabePlausiKonfiguration stimmeingabePlausiKonfiguration, Messages messages) {
    super(new StimmeingabeAnzahlComparedToStimmeingabeAnzahlenPlausiDefinition(StimmeingabeAnzahlReference.SYSTEM_GRUPPE_STIMMZETTEL_GESAMT, comparedToOperator,
        StimmeingabeAnzahlReference.SYSTEM_GRUPPE_WAEHLER_GESAMT), stimmeingabenWaehlerGesamt, stimmeingabePlausiKonfiguration, messages);

    this.stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenig = stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenig;
    this.stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenigHavingAnzahlGroesserNull = existsStimmzetteleingabeHavingAnzahlGroesserNull(
        this.stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenig);

    this.stimmzetteleingabeStimmzettelEingenommenAbweichendZuviel = stimmzetteleingabeStimmzettelEingenommenAbweichendZuviel;
    this.stimmzetteleingabeStimmzettelEingenommenAbweichendZuvielHavingAnzahlGroesserNull = existsStimmzetteleingabeHavingAnzahlGroesserNull(
        this.stimmzetteleingabeStimmzettelEingenommenAbweichendZuviel);

    this.stimmzetteleingabenStimmzettelEingenommenAbweichendGrund = stimmzetteleingabenStimmzettelEingenommenAbweichendGrund.stream().filter(Objects::nonNull).collect(toList());
    this.stimmzetteleingabenStimmzettelEingenommenAbweichendGrundHavingAnzahlGroesserNull = !this.stimmzetteleingabenStimmzettelEingenommenAbweichendGrund.isEmpty()
        && this.stimmzetteleingabenStimmzettelEingenommenAbweichendGrund.stream().anyMatch(this::existsStimmzetteleingabeHavingAnzahlGroesserNull);
  }

  protected boolean existsStimmzetteleingabenStimmzettelEingenommenAbweichendHavingAnzahlGroesserNull() {
    return existsStimmzetteleingabeStimmzettelEingenommenAbweichendZuwenigHavingAnzahlGroesserNull() || existsStimmzetteleingabeStimmzettelEingenommenAbweichendZuvielHavingAnzahlGroesserNull()
        || existsStimmzetteleingabenStimmzettelEingenommenAbweichendGrundHavingAnzahlGroesserNull();
  }

  protected boolean existsStimmzetteleingabeStimmzettelEingenommenAbweichendZuwenigHavingAnzahlGroesserNull() {
    return stimmzetteleingabeStimmzettelEingenommenAbweichendZuwenigHavingAnzahlGroesserNull;
  }

  protected boolean existsStimmzetteleingabeStimmzettelEingenommenAbweichendZuvielHavingAnzahlGroesserNull() {
    return stimmzetteleingabeStimmzettelEingenommenAbweichendZuvielHavingAnzahlGroesserNull;
  }

  protected boolean existsStimmzetteleingabenStimmzettelEingenommenAbweichendGrundHavingAnzahlGroesserNull() {
    return stimmzetteleingabenStimmzettelEingenommenAbweichendGrundHavingAnzahlGroesserNull;
  }

  private boolean existsStimmzetteleingabeHavingAnzahlGroesserNull(Stimmeingabe stimmzetteleingabe) {
    return stimmzetteleingabe != null && stimmzetteleingabe.hasAnzahlGroesserNull();
  }
}
