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

import java.util.Optional;

import javax.enterprise.inject.Specializes;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.NlSystemGruppe;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiGebietsart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;

@Specializes
public class NlStimmeingabeKopfzahlKonfiguration extends StimmeingabeKopfzahlKonfiguration {

  private static final long serialVersionUID = 1L;

  private static final NlSystemGruppe WAEHLER = NlSystemGruppe.WAEHLER;

  private static final NlSystemGruppe STIMMZETTEL_EINGENOMMEN = NlSystemGruppe.STIMMZETTEL_EINGENOMMEN;

  private static final NlSystemGruppe STIMMZETTEL_EINGENOMMEN_ABWEICHEND = NlSystemGruppe.STIMMZETTEL_EINGENOMMEN_ABWEICHEND;

  public NlStimmeingabeKopfzahlKonfiguration() {
    super();
  }

  @Override
  public boolean isWaehlerGesamtBeiStimmeingabeAlsErstesZuErfassen(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return false;
  }

  public boolean isWaehlerMitVollmachtBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, WAEHLER, Stimmenart.MIT_VOLLMACHT);
  }

  public boolean isStimmzettelEingenommenGesamtBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN, Stimmenart.GESAMT_EINGENOMMEN);
  }

  public boolean isStimmzettelEingenommenGesamtBeiStimmeingabeRelevant(Wahl wahl, WahlartErgebnisart ergebnisart, Optional<StimmeingabePlausiGebietsart> gebietsart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahl, ergebnisart, gebietsart, STIMMZETTEL_EINGENOMMEN, Stimmenart.GESAMT_EINGENOMMEN);
  }

  public boolean isStimmzettelEingenommenAbweichendBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    NlSystemGruppe nlSystemGruppe = STIMMZETTEL_EINGENOMMEN_ABWEICHEND;

    return nlSystemGruppe.getStimmenarten().stream().anyMatch(stimmenart -> isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, nlSystemGruppe, stimmenart));
  }

  public boolean isStimmzettelEingenommenAbweichendBeiStimmeingabeRelevant(Wahl wahl, WahlartErgebnisart ergebnisart, Optional<StimmeingabePlausiGebietsart> gebietsart) {
    NlSystemGruppe nlSystemGruppe = STIMMZETTEL_EINGENOMMEN_ABWEICHEND;

    return nlSystemGruppe.getStimmenarten().stream().anyMatch(stimmenart -> isGruppeMitStimmenartBeiStimmeingabeRelevant(wahl, ergebnisart, gebietsart, nlSystemGruppe, stimmenart));
  }

  public boolean isStimmzettelEingenommenAbweichendZuvielBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_ZUVIEL);
  }

  public boolean isStimmzettelEingenommenAbweichendZuwenigBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_ZUWENIG);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundAusgegebenNichtAbgegebenBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_AUSGEGEBEN_NICHT_ABGEGEBEN);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundAusgegebenZuvielBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_AUSGEGEBEN_ZUVIEL);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundAusgegebenZuwenigBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_AUSGEGEBEN_ZUWENIG);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundInWahlbriefZuvielBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_IN_WAHLBRIEF_ZUVIEL);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundInWahlbriefZuwenigBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_IN_WAHLBRIEF_ZUWENIG);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundVerlorenBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_VERLOREN);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundUnbekanntBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_UNBEKANNT);
  }

  public boolean isStimmzettelEingenommenAbweichendGrundSonstigesBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, STIMMZETTEL_EINGENOMMEN_ABWEICHEND, Stimmenart.GESAMT_ABWEICHEND_GRUND_SONSTIGES);
  }

  public boolean isGruppeMitStimmenartBeiStimmeingabeRelevant(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart, NlSystemGruppe nlSystemGruppe, Stimmenart stimmenart) {
    return nlSystemGruppe.isStimmenartRelevantAufGebiet(wahldurchfuehrungsgebiet, ergebnisart, stimmenart);
  }

  public boolean isGruppeMitStimmenartBeiStimmeingabeRelevant(Wahl wahl, WahlartErgebnisart ergebnisart, Optional<StimmeingabePlausiGebietsart> gebietsart, NlSystemGruppe nlSystemGruppe,
      Stimmenart stimmenart) {
    return nlSystemGruppe.isStimmenartRelevantBeiStimmeingabe(wahl, ergebnisart, gebietsart, stimmenart);
  }
}
