
package de.ivu.elect.presentation.wahlbeteiligung.form;

import static javax.faces.application.FacesMessage.SEVERITY_ERROR;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiTyp;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.faces.Messages;

// ELECT-8463
public class WahlbeteiligungAnzahlWaehlerGesamtFacesValidator implements Validator {

  private static final String DEFAULT_ERROR_MSG_KEY_WAEHLER_GESAMT_ANZAHL_KONVERTIERBAR = "StimmeingabePlausiTyp." + StimmeingabePlausiTyp.STIMMEINGABE_ANZAHL_KONVERTIERBAR + ".fehlermeldung";

  private static final String DEFAULT_ERROR_MSG_KEY_WAEHLER_GESAMT_ANZAHL_KLEINER_GLEICH_WAHLBERECHTIGTE_GESAMT_ANZAHL = "StimmeingabePlausiTyp."
      + StimmeingabePlausiTyp.WAEHLER_GESAMT_ANZAHL_KLEINER_GLEICH_WAHLBERECHTIGTE_GESAMT_ANZAHL + ".fehlermeldung";

  private final String errorMsgWaehlerGesamtAnzahlNichtKonvertierbar;

  private final String errorMsgWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl;

  private final Long anzahlWahlberechtigteGesamt;

  public WahlbeteiligungAnzahlWaehlerGesamtFacesValidator(Messages messages, Wahl wahl, @Nullable Long anzahlWahlberechtigteGesamt) {
    super();

    String errorMsgKeyWahlartSuffix = "";

    if (wahl != null && wahl.getWahlart() != null) {
      errorMsgKeyWahlartSuffix = "." + wahl.getWahlart().getWahlartNameNormalized();
    }

    String errorMsgKeyWaehlerGesamtAnzahlNichtKonvertierbar = DEFAULT_ERROR_MSG_KEY_WAEHLER_GESAMT_ANZAHL_KONVERTIERBAR;

    if (messages.isMessageKeyVorhanden(errorMsgKeyWaehlerGesamtAnzahlNichtKonvertierbar + errorMsgKeyWahlartSuffix)) {
      errorMsgKeyWaehlerGesamtAnzahlNichtKonvertierbar += errorMsgKeyWahlartSuffix;
    }

    String errorMsgKeyWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl = DEFAULT_ERROR_MSG_KEY_WAEHLER_GESAMT_ANZAHL_KLEINER_GLEICH_WAHLBERECHTIGTE_GESAMT_ANZAHL;

    if (messages.isMessageKeyVorhanden(errorMsgKeyWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl + errorMsgKeyWahlartSuffix)) {
      errorMsgKeyWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl += errorMsgKeyWahlartSuffix;
    }

    this.errorMsgWaehlerGesamtAnzahlNichtKonvertierbar = messages.getMessageForMessageKey(errorMsgKeyWaehlerGesamtAnzahlNichtKonvertierbar);
    this.errorMsgWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl = messages.getMessageForMessageKey(errorMsgKeyWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl);

    this.anzahlWahlberechtigteGesamt = anzahlWahlberechtigteGesamt;
  }

  public String getErrorMsgWaehlerGesamtAnzahlNichtKonvertierbar() {
    return errorMsgWaehlerGesamtAnzahlNichtKonvertierbar;
  }

  public String getErrorMsgWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl() {
    return errorMsgWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl;
  }

  public Long getAnzahlWahlberechtigteGesamt() {
    return anzahlWahlberechtigteGesamt;
  }

  @Override
  public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if (value != null) {
      validate((Long) value, getAnzahlWahlberechtigteGesamt());
    }
  }

  private void validate(@Nonnull Long anzahlWaehlerGesamt, @Nullable Long anzahlWahlberechtigteGesamt) {
    if (anzahlWaehlerGesamt < 0) {
      throwValidatorException(getErrorMsgWaehlerGesamtAnzahlNichtKonvertierbar());
    }

    if (anzahlWahlberechtigteGesamt != null && anzahlWahlberechtigteGesamt >= 0 && anzahlWaehlerGesamt > anzahlWahlberechtigteGesamt) {
      throwValidatorException(getErrorMsgWaehlerGesamtAnzahlNichtKleinerGleichWahlberechtigteGesamtAnzahl());
    }
  }

  private void throwValidatorException(String msg) {
    throw new ValidatorException(new FacesMessage(SEVERITY_ERROR, msg, msg));
  }
}
