
package de.ivu.elect.business.stimmen.boundary;

import static org.apache.commons.lang3.StringUtils.isNoneBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.kandidatur.boundary.WaehlerBenannteKandidaturKonfiguration;

public class KopfzahlLabelGenerator extends AbstractStimmeLabelGenerator {

  private static final long serialVersionUID = 1L;

  private static final String MSG_KEY_INFIX_OHNE_WAHLSCHEIN = Stimmenart.OHNE_WAHLSCHEIN.name();

  private static final String MSG_KEY_INFIX_MIT_WAHLSCHEIN = Stimmenart.MIT_WAHLSCHEIN.name();

  // Cf. Stimmenart#ALS_URNENWAHL_IN_URNE
  private static final String MSG_KEY_INFIX_MIT_WAHLSCHEIN_IN_URNENWAHL_ANTEIL_AUS_URNENWAHL = "MIT_WAHLSCHEIN_ALS_URNENWAHL_IN_URNE";

  // Cf. Stimmenart#ALS_BRIEFWAHL_IN_URNE
  private static final String MSG_KEY_INFIX_MIT_WAHLSCHEIN_IN_URNENWAHL_ANTEIL_AUS_BRIEFWAHL = "MIT_WAHLSCHEIN_ALS_BRIEFWAHL_IN_URNE";

  private static final String MSG_KEY_INFIX_NICHT_IM_WAEHLERVERZEICHNIS = Stimmenart.NICHT_IM_WAEHLERVERZEICHNIS.name();

  public KopfzahlLabelGenerator() {
    super();
  }

  public KopfzahlLabelGenerator(StimmeLabelMessages stimmeLabelMessages, WaehlerBenannteKandidaturKonfiguration waehlerBenannteKandidaturKonfiguration) {
    super(stimmeLabelMessages, waehlerBenannteKandidaturKonfiguration);
  }

  public String getWaehlerBezeichnungSingular(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getSingularOrDefault(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_WAEHLER, "Wähler");
  }

  public String getWaehlerBezeichnungPlural(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getPluralOrDefault(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_WAEHLER, "Wähler");
  }

  public String getAnzahlWaehlerOhneWahlscheinKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_OHNE_WAHLSCHEIN, "B2"); // ELECT-4430 wollte am 16.06.16, dass ich hier B2 als Default Eintrage...viel Spaß...
  }

  public String getAnzahlWaehlerOhneWahlscheinBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_OHNE_WAHLSCHEIN, "Wähler ohne Wahlschein");
  }

  public String getAnzahlWaehlerMitWahlscheinKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN, "B1"); // ELECT-4430 wollte am 16.06.16, dass ich hier B1 als Default Eintrage...viel Spaß...
  }

  public String getAnzahlWaehlerMitWahlscheinBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN, "Wähler mit Wahlschein");
  }

  public String getAnzahlWaehlerMitWahlscheinInUrnenwahlAnteilAusUrnenwahlKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN_IN_URNENWAHL_ANTEIL_AUS_URNENWAHL, "B2a");
  }

  public String getAnzahlWaehlerMitWahlscheinInUrnenwahlAnteilAusUrnenwahlBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN_IN_URNENWAHL_ANTEIL_AUS_URNENWAHL, "davon Urnenwähler");
  }

  public String getAnzahlWaehlerMitWahlscheinInUrnenwahlAnteilAusBriefwahlKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN_IN_URNENWAHL_ANTEIL_AUS_BRIEFWAHL, "B2");
  }

  public String getAnzahlWaehlerMitWahlscheinInUrnenwahlAnteilAusBriefwahlBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN_IN_URNENWAHL_ANTEIL_AUS_BRIEFWAHL, "davon Briefwähler (in Urnenwahllokal erfasst)");
  }

  public String getAnzahlWaehlerGesamtKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_GESAMT, "B");
  }

  public String getAnzahlWaehlerGesamtBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_GESAMT, "Wähler insgesamt");
  }

  public String getAnzahlWaehlerGesamtOhneWahlscheinPlusMitWahlscheinKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, "GESAMT_OHNE_WAHLSCHEIN_PLUS_MIT_WAHLSCHEIN", "B");
  }

  public String getAnzahlWaehlerKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlWaehlerKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlWaehlerKennung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlWaehlerKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = MSG_KEY_INFIX_WAEHLER + ".ANZAHL." + msgKeyInfixStimmenart;

    return getKennungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getAnzahlWaehlerBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlWaehlerBezeichnung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlWaehlerBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlWaehlerBezeichnung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlWaehlerBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = MSG_KEY_INFIX_WAEHLER + ".ANZAHL." + msgKeyInfixStimmenart;

    return getBezeichnungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getWahlberechtigteBezeichnungSingular(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getSingularOrDefault(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_WAHLBERECHTIGTE, "Wahlberechtigter");
  }

  public String getWahlberechtigteBezeichnungPlural(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getPluralOrDefault(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_WAHLBERECHTIGTE, "Wahlberechtigte");
  }

  public String getPruefkennzeichenWahlberechtigteKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return "";
  }

  public String getPruefkennzeichenWahlberechtigteBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getMessage(Stimmenart.PRUEFKENNZEICHEN);
  }

  public String getAnzahlWahlberechtigteOhneWahlscheinKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_OHNE_WAHLSCHEIN, "A1");
  }

  public String getAnzahlWahlberechtigteOhneWahlscheinBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_OHNE_WAHLSCHEIN, "Wahlberechtigte ohne Vermerk „W“ (Wahlschein)");
  }

  public String getAnzahlWahlberechtigteMitWahlscheinKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN, "A2");
  }

  public String getAnzahlWahlberechtigteMitWahlscheinBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_MIT_WAHLSCHEIN, "Wahlberechtigte mit Vermerk „W“ (Wahlschein)");
  }

  public String getAnzahlWahlberechtigteNichtImWaehlerverzeichnisKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_NICHT_IM_WAEHLERVERZEICHNIS, "A3");
  }

  public String getAnzahlWahlberechtigteNichtImWaehlerverzeichnisBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_NICHT_IM_WAEHLERVERZEICHNIS, "Wahlberechtigte nicht im Wählerverzeichnis");
  }

  public String getAnzahlWahlberechtigteGesamtKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_GESAMT, "A");
  }

  public String getAnzahlWahlberechtigteGesamtBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteBezeichnung(wahldurchfuehrungsgebiet, MSG_KEY_INFIX_GESAMT, "Wahlberechtigte insgesamt");
  }

  public String getAnzahlWahlberechtigteGesamtOhneWahlscheinPlusMitWahlscheinSummanden(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    String anzahlWahlberechtigteOhneWahlscheinKennung = getAnzahlWahlberechtigteOhneWahlscheinKennung(wahldurchfuehrungsgebiet);
    String anzahlWahlberechtigteMitWahlscheinKennung = getAnzahlWahlberechtigteMitWahlscheinKennung(wahldurchfuehrungsgebiet);

    if (isNoneBlank(anzahlWahlberechtigteOhneWahlscheinKennung, anzahlWahlberechtigteMitWahlscheinKennung)) {
      return anzahlWahlberechtigteOhneWahlscheinKennung + " + " + anzahlWahlberechtigteMitWahlscheinKennung;
    }

    return getAnzahlWahlberechtigteGesamtKennung(wahldurchfuehrungsgebiet);
  }

  public String getAnzahlWahlberechtigteGesamtOhneWahlscheinPlusMitWahlscheinPlusNichtImWaehlerverzeichnisSummanden(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    String anzahlWahlberechtigteOhneWahlscheinKennung = getAnzahlWahlberechtigteOhneWahlscheinKennung(wahldurchfuehrungsgebiet);
    String anzahlWahlberechtigteMitWahlscheinKennung = getAnzahlWahlberechtigteMitWahlscheinKennung(wahldurchfuehrungsgebiet);

    if (isNoneBlank(anzahlWahlberechtigteOhneWahlscheinKennung, anzahlWahlberechtigteMitWahlscheinKennung)) {
      String anzahlWahlberechtigteNichtImWaehlerverzeichnisKennung = getAnzahlWahlberechtigteNichtImWaehlerverzeichnisKennung(wahldurchfuehrungsgebiet);

      if (isNotBlank(anzahlWahlberechtigteNichtImWaehlerverzeichnisKennung)) {
        return anzahlWahlberechtigteOhneWahlscheinKennung + " + " + anzahlWahlberechtigteMitWahlscheinKennung + " + " + anzahlWahlberechtigteNichtImWaehlerverzeichnisKennung;
      }

      return anzahlWahlberechtigteOhneWahlscheinKennung + " + " + anzahlWahlberechtigteMitWahlscheinKennung;
    }

    return getAnzahlWahlberechtigteGesamtKennung(wahldurchfuehrungsgebiet);
  }

  public String getAnzahlWahlberechtigteGesamtOhneWahlscheinPlusMitWahlscheinKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, "GESAMT_OHNE_WAHLSCHEIN_PLUS_MIT_WAHLSCHEIN", "A1 + A2");
  }

  public String getAnzahlWahlberechtigteGesamtOhneWahlscheinPlusMitWahlscheinPlusNichtImWaehlerverzeichnisKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, "GESAMT_OHNE_WAHLSCHEIN_PLUS_MIT_WAHLSCHEIN_PLUS_NICHT_IM_WAEHLERVERZEICHNIS", "A");
  }

  public String getAnzahlWahlberechtigteKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlWahlberechtigteKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlWahlberechtigteKennung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlWahlberechtigteKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = MSG_KEY_INFIX_WAHLBERECHTIGTE + ".ANZAHL." + msgKeyInfixStimmenart;

    return getKennungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getAnzahlWahlberechtigteBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlWahlberechtigteBezeichnung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlWahlberechtigteBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlWahlberechtigteBezeichnung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlWahlberechtigteBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = MSG_KEY_INFIX_WAHLBERECHTIGTE + ".ANZAHL." + msgKeyInfixStimmenart;

    return getBezeichnungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getAnzahlGueltigeKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlGueltigeKennung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlGueltigeKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlGueltigeKennung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlGueltigeKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = msgKeyInfixStimmenart + ".ANZAHL." + MSG_KEY_INFIX_GUELTIGE + ".GESAMT";

    return getKennungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getAnzahlGueltigeBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlGueltigeBezeichnung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlGueltigeBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlGueltigeBezeichnung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlGueltigeBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = msgKeyInfixStimmenart + ".ANZAHL." + MSG_KEY_INFIX_GUELTIGE + ".GESAMT";

    return getBezeichnungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getAnzahlUngueltigeKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlUngueltigeKennung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlUngueltigeKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlUngueltigeKennung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlUngueltigeKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = msgKeyInfixStimmenart + ".ANZAHL." + MSG_KEY_INFIX_UNGUELTIGE + ".GESAMT";

    return getKennungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getAnzahlUngueltigeBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return getAnzahlUngueltigeBezeichnung(wahldurchfuehrungsgebiet, stimmenart, "");
  }

  private String getAnzahlUngueltigeBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart, String defaultValue) {
    return getAnzahlUngueltigeBezeichnung(wahldurchfuehrungsgebiet, stimmenart.name(), defaultValue);
  }

  private String getAnzahlUngueltigeBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, String msgKeyInfixStimmenart, String defaultValue) {
    String msgKeyInfix = msgKeyInfixStimmenart + ".ANZAHL." + MSG_KEY_INFIX_UNGUELTIGE + ".GESAMT";

    return getBezeichnungOrDefault(wahldurchfuehrungsgebiet, msgKeyInfix, defaultValue);
  }

  public String getAnzahlUebrigeKennung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return formatAnzahlUebrigeStimmenartKennung(wahldurchfuehrungsgebiet, stimmenart);
  }

  public String getAnzahlUebrigeBezeichnung(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmenart stimmenart) {
    return formatAnzahlUebrigeStimmenartBezeichnung(wahldurchfuehrungsgebiet, stimmenart);
  }
}
