
package de.ivu.elect.business.person.entity;

import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.replaceIgnoreCase;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;

import java.text.SimpleDateFormat;

import javax.faces.application.FacesMessage;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import de.ivu.elect.business.person.entity.PersonendatenProperties.StimmbezirkSchluesselProperty;
import de.ivu.elect.jee.faces.Messages;

public class NlGeburtsdatumProperty extends StimmbezirkSchluesselProperty {

  private static final String GEBURTSDATUM_ERFASST_DATE_FORMAT_PATTERN = NlPersonendaten.GEBURTSDATUM_ERFASST_DATE_FORMAT_PATTERN;

  private static final String GEBURTSDATUM_ERFASST_REG_EX = NlPersonendaten.GEBURTSDATUM_ERFASST_REG_EX;

  public NlGeburtsdatumProperty(Personendaten personendaten) {
    super(personendaten);

    getValidators().add(createGeburtsdatumRegexValidator(getMessages()));
  }

  @Override
  public int getDefaultMaxLength() {
    return GEBURTSDATUM_ERFASST_DATE_FORMAT_PATTERN.length();
  }

  @Override
  public String getDefaultLabel() {
    return getMessage(PersonendatenConstants.MESSAGE_KEY_GEBURTSDATUM_EINZAHL);
  }

  @Override
  public void setValue(String value) {
    if (entity == null) {
      super.setValue(value);
    } else {
      new NlPersonendaten(entity).setGeburtsdatumErfasst(normalisiere(value));
    }
  }

  private String normalisiere(String value) {
    if (value == null) {
      return null;
    }

    // ELECTVAPP-1283
    String normalisiertesDatum = value.replace("00-", "XX-"); // unbekannter Tag oder Monat zu XX normalisieren
    normalisiertesDatum = normalisiertesDatum.replace("0000", "XXXX"); // unbekanntes Jahr zu XXXX normalisieren

    return normalisiertesDatum;
  }

  public static Validator createGeburtsdatumRegexValidator(Messages messages) {
    return (facesContext, uiComponent, value) -> {
      if (value != null) {
        String valueOrBlank = trimToEmpty(value.toString());

        if (isNotBlank(valueOrBlank)) { // Nur gesetzte Werte validieren -> für Pflichtfeld required == true verwenden!
          if (valueOrBlank.matches(GEBURTSDATUM_ERFASST_REG_EX)) {
            // ELECTVAPP-1425, RegEx trifft -> Pattern muss ??-??-????, also mit Trennzeichen '-', sein!
            String valueNormalized = valueOrBlank;
            valueNormalized = replaceIgnoreCase(valueNormalized, "00-", "01-");
            valueNormalized = replaceIgnoreCase(valueNormalized, "xx-", "01-");
            valueNormalized = replaceIgnoreCase(valueNormalized, "0000", "2000"); // 2000 -> Schaltjahr...
            valueNormalized = replaceIgnoreCase(valueNormalized, "xxxx", "2000");

            try {
              SimpleDateFormat simpleDateFormat = new SimpleDateFormat(GEBURTSDATUM_ERFASST_DATE_FORMAT_PATTERN);
              simpleDateFormat.setLenient(false);
              simpleDateFormat.parse(valueNormalized);
            } catch (Exception ex) {
              String errorMessage = messages.getMessageForMessageKey("personendaten.geburtsdatum.format.error.invalid");

              throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, errorMessage));
            }
          } else {
            String errorMessage = messages.getMessageForMessageKey("personendaten.geburtsdatum.format.error");

            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, errorMessage));
          }
        }
      }
    };
  }
}
