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

import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiFehlerart.ERROR;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiFehlerart.WARNING;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp.BLANKO_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_WAEHLER_GESAMT_ANZAHL_ANTEIL;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp.GRUPPE_LISTENSTIMMEN_ANZAHL_GLEICH_LISTENKANDIDATUR_LISTENSTIMMEN_ANZAHLEN_SUMME;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp.GUELTIGE_LISTENSTIMMEN_ANZAHL_GLEICH_GRUPPE_LISTENSTIMMEN_ANZAHLEN_SUMME;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp.STIMMEINGABE_ANZAHLEN_UNGLEICH_STIMMEINGABE_ANZAHLEN_IN_ANDEREN_ERFASSUNGSGEBIETEN;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp.STIMMZETTEL_GESAMT_ANZAHL_GLEICH_STIMMZETTEL_ANZAHLEN_SUMME;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp.UNGUELTIGE_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_WAEHLER_GESAMT_ANZAHL_ANTEIL;
import static de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp.WAEHLER_GESAMT_ANZAHL_GLEICH_WAEHLER_ANZAHLEN_SUMME;

import java.util.Collection;
import java.util.EnumSet;

import javax.inject.Inject;

import de.ivu.elect.business.stimmeingabe.control.NlDefaultListenwahlStimmeingabeKonfiguration;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiErgebniseingangsart;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiGebietsart;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp;
import de.ivu.elect.business.stimmen.boundary.NlStimmeLabelMessages;
import de.ivu.elect.business.wahl.boundary.WahlartTemplate;
import de.ivu.elect.business.wahl.entity.CommonWahlart;
import de.ivu.elect.business.wahl.entity.NlWahlart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahlart;
import de.ivu.elect.business.wahl.entity.WahlartSitzberechnungsalgorithmus;

public class NlDefaultListenwahlStimmeingabePlausiDefinitions extends AbstractNlStimmeingabePlausiDefinitions {

  public static final StimmeingabePlausiTyp STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_GLEICH_SYSTEM_GRUPPE_LISTENSTIMMEN_ANZAHLEN_SUMME = STIMMZETTEL_GESAMT_ANZAHL_GLEICH_STIMMZETTEL_ANZAHLEN_SUMME;

  public static final StimmeingabePlausiTyp BLANKO_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_ANTEIL = BLANKO_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_WAEHLER_GESAMT_ANZAHL_ANTEIL;

  public static final StimmeingabePlausiTyp UNGUELTIGE_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_ANTEIL = UNGUELTIGE_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_WAEHLER_GESAMT_ANZAHL_ANTEIL;

  public static final String EXTRA_HINWEIS_PSB_MSG_KEY = "NlDefaultListenwahlStimmeingabePlausiDefinitions.EXTRA_HINWEIS_PSB.fehlermeldung.KANN"; // ELECT-15746

  public static final Collection<StimmeingabePlausiTyp> EXTRA_HINWEIS_PSB_STIMMEINGABE_PLAUSI_TYPEN = EnumSet.of( // ELECT-15746, "Let op: Heeft u geen invoerfout gemaakt, [...] GSB kan onderzoeken [...]"
      WAEHLER_GESAMT_ANZAHL_GLEICH_WAEHLER_ANZAHLEN_SUMME, // ELECTVAPP-2061

      BLANKO_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_ANTEIL, // ELECTVAPP-2157
      UNGUELTIGE_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_ANTEIL, // ELECTVAPP-2157

      STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_GLEICH_SYSTEM_GRUPPE_LISTENSTIMMEN_ANZAHLEN_SUMME, // ELECTVAPP-2062

      STIMMZETTEL_EINGENOMMEN_ABWEICHEND_ZUVIEL_ANZAHL_GLEICH_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_MINUS_WAEHLER_GESAMT_ANZAHL, // ELECTVAPP-2063
      STIMMZETTEL_EINGENOMMEN_ABWEICHEND_ZUVIEL_ANZAHL_GLEICH_STIMMZETTEL_EINGENOMMEN_ABWEICHEND_ZUVIEL_GRUENDE_ANZAHLEN_SUMME, //
      STIMMZETTEL_EINGENOMMEN_ABWEICHEND_ZUWENIG_ANZAHL_GLEICH_WAEHLER_GESAMT_ANZAHL_MINUS_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL, // ELECTVAPP-2064
      STIMMZETTEL_EINGENOMMEN_ABWEICHEND_ZUWENIG_ANZAHL_GLEICH_STIMMZETTEL_EINGENOMMEN_ABWEICHEND_ZUWENIG_GRUENDE_ANZAHLEN_SUMME, //

      StimmeingabePlausiTyp.GUELTIGE_LISTENSTIMMEN_ANZAHL_GLEICH_GRUPPE_LISTENSTIMMEN_ANZAHLEN_SUMME, //

      StimmeingabePlausiTyp.GRUPPE_LISTENSTIMMEN_ANZAHL_GLEICH_LISTENKANDIDATUR_LISTENSTIMMEN_ANZAHLEN_SUMME, //

      StimmeingabePlausiTyp.WAHLBERECHTIGTE_NICHT_IM_WAEHLERVERZEICHNIS_ANZAHL_GLEICH_NULL, //

      StimmeingabePlausiTyp.BLANKO_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_WAEHLER_GESAMT_ANZAHL_ANTEIL, //
      StimmeingabePlausiTyp.UNGUELTIGE_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_WAEHLER_GESAMT_ANZAHL_ANTEIL //
  );

  @Inject
  private transient NlDefaultListenwahlStimmeingabeKonfiguration defaultListenwahlStimmeingabeKonfiguration;

  public NlDefaultListenwahlStimmeingabePlausiDefinitions() {
    super(new WahlartTemplate() {

      @Override
      public String getWahlartName() {
        return NlStimmeLabelMessages.DEFAULT_LISTENWAHL;
      }

      @Override
      public CommonWahlart getCommonWahlart() {
        return CommonWahlart.UNBEKANNT;
      }

      @Override
      public WahlartSitzberechnungsalgorithmus getSitzberechnungsalgorithmus() {
        return WahlartSitzberechnungsalgorithmus.KEIN;
      }
    });
  }

  @Override
  public boolean isApplicable(Wahlart wahlart) {
    return NlWahlart.isListenwahl(wahlart);
  }

  protected NlDefaultListenwahlStimmeingabeKonfiguration getStimmeingabeKonfiguration() {
    return defaultListenwahlStimmeingabeKonfiguration;
  }

  @Override
  protected void initDefaultsAlleGebietsarten(StimmeingabePlausiDefinitionsContext context, Wahl wahl, StimmeingabePlausiErgebniseingangsart ergebniseingangsart) {
    super.initDefaultsAlleGebietsarten(context, wahl, ergebniseingangsart);

    for (StimmeingabePlausiGebietsart gebietsart : StimmeingabePlausiGebietsart.values()) {
      initDefault(ergebniseingangsart, gebietsart, GUELTIGE_LISTENSTIMMEN_ANZAHL_GLEICH_GRUPPE_LISTENSTIMMEN_ANZAHLEN_SUMME, ERROR); // ELECTVAPP-37, #3

      if (isStimmzettelEingenommenGesamtBeiStimmeingabeRelevant(wahl, ergebniseingangsart, gebietsart)) {
        initDefault(ergebniseingangsart, gebietsart, BLANKO_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_ANTEIL, WARNING,
            new StimmeingabeAnzahlComparedToStimmeingabeAnzahlAnteilPlausiCustomData(0.03D)); // ELECTVAPP-37, #4, ELECTVAPP-2157 -> 5% zu 3%

        initDefault(ergebniseingangsart, gebietsart, UNGUELTIGE_LISTENSTIMMEN_ANZAHL_KLEINER_GLEICH_STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_ANTEIL, WARNING,
            new StimmeingabeAnzahlComparedToStimmeingabeAnzahlAnteilPlausiCustomData(0.03D)); // ELECTVAPP-37, #5, ELECTVAPP-2157 -> 5% zu 3%

        initDefault(ergebniseingangsart, gebietsart, STIMMZETTEL_EINGENOMMEN_GESAMT_ANZAHL_GLEICH_SYSTEM_GRUPPE_LISTENSTIMMEN_ANZAHLEN_SUMME, isPsb(wahl) || isNbsb(wahl) ? ERROR : WARNING); // ELECTVAPP-37, #6, ELECTVAPP-2062 -> PSB/NBSB = ERROR, HSB/CSB = WARNING
      }

      initDefault(ergebniseingangsart, gebietsart, GRUPPE_LISTENSTIMMEN_ANZAHL_GLEICH_LISTENKANDIDATUR_LISTENSTIMMEN_ANZAHLEN_SUMME, ERROR); // ELECTVAPP-37, #12

      initDefault(ergebniseingangsart, gebietsart, STIMMEINGABE_ANZAHLEN_UNGLEICH_STIMMEINGABE_ANZAHLEN_IN_ANDEREN_ERFASSUNGSGEBIETEN, WARNING); // ELECTVAPP-151, ELECTVAPP-37, #15
    }
  }
}
