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

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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 AbstractNlStimmzettelEingenommenAbweichendAnzahlGleichAnzahlSollPlausi extends AbstractStimmeingabeAnzahlComparedToPlausi {

  private final Collection<Stimmeingabe> stimmeingabenWaehlerGesamt;

  private final Stimmeingabe stimmzetteleingabeStimmzettelEingenommenGesamt;

  public AbstractNlStimmzettelEingenommenAbweichendAnzahlGleichAnzahlSollPlausi(StimmeingabeAnzahlReference stimmeingabeAnzahlReference, Collection<Stimmeingabe> stimmeingabenWaehlerGesamt,
      Stimmeingabe stimmzetteleingabeStimmzettelEingenommenGesamt, StimmeingabePlausiKonfiguration stimmeingabePlausiKonfiguration, Messages messages) {
    super(new StimmeingabeAnzahlComparedToStimmeingabeAnzahlenPlausiDefinition(stimmeingabeAnzahlReference, StimmeingabeAnzahlComparedToOperator.EQUAL_TO,
        StimmeingabeAnzahlReference.SYSTEM_GRUPPE_WAEHLER_GESAMT, StimmeingabeAnzahlReference.SYSTEM_GRUPPE_STIMMZETTEL_GESAMT), stimmeingabePlausiKonfiguration, messages);

    this.stimmeingabenWaehlerGesamt = stimmeingabenWaehlerGesamt.stream().filter(Objects::nonNull).collect(toList());

    this.stimmzetteleingabeStimmzettelEingenommenGesamt = stimmzetteleingabeStimmzettelEingenommenGesamt;
  }

  @Override
  protected boolean isPlausibilisierenZulaessig(Stimmeingabe stimmeingabe) {
    return super.isPlausibilisierenZulaessig(stimmeingabe) && !stimmeingabenWaehlerGesamt.isEmpty() && stimmzetteleingabeStimmzettelEingenommenGesamt != null;
  }

  @Override
  protected boolean isPlausiResultCalculatedAutomatischKorrigierbar() {
    return false; // ELECT-10060
  }

  @Override
  protected Long getComparedToValue() {
    return getComparedToValue(getAnzahlWaehlerGesamt(), getAnzahlStimmzettelEingenommenGesamt());
  }

  protected abstract Long getComparedToValue(long anzahlWaehlerGesamt, long anzahlStimmzettelEingenommenGesamt);

  private long getAnzahlStimmzettelEingenommenGesamt() {
    return fixNullToZero(stimmzetteleingabeStimmzettelEingenommenGesamt);
  }

  private long getAnzahlWaehlerGesamt() {
    return stimmeingabenWaehlerGesamt.stream().mapToLong(Stimmeingabe::getAnzahl).sum();
  }

  @Override
  protected List<Object> getStimmeingabefehlerBeschreibungParameters(Stimmeingabe stimmeingabe) {
    List<Object> result = new ArrayList<>(super.getStimmeingabefehlerBeschreibungParameters(stimmeingabe));
    result.add(getAnzahlWaehlerGesamt());
    result.add(getAnzahlStimmzettelEingenommenGesamt());

    return result;
  }
}
