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

import java.util.Objects;
import java.util.function.Supplier;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.person.boundary.SearchParametersMitPersonendaten;
import de.ivu.elect.business.person.boundary.SearchParametersMitPersonendatenNamen;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.Property;
import de.ivu.elect.jee.presentation.dynamicform.converter.AutoFormatDateTimeConverter;
import de.ivu.elect.jee.presentation.search.AbstractSearchParameters;
import de.ivu.elect.presentation.ViewFormBuilder;

public class PersonendatenSearchFormBuilder extends ViewFormBuilder {

  private static final long serialVersionUID = 1L;

  private static final Logger LOG = LoggerFactory.getLogger(PersonendatenSearchFormBuilder.class);

  public PersonendatenSearchFormBuilder() {
    super();
  }

  public void addPersonendatenProperties(FormBuilder formBuilder, SearchParametersMitPersonendaten searchParametersMitPersonendaten) {
    requireModifiablePropertyInstance(searchParametersMitPersonendaten, "FamiliennameProperty", searchParametersMitPersonendaten::getFamiliennameProperty);
    requireModifiablePropertyInstance(searchParametersMitPersonendaten, "VornameProperty", searchParametersMitPersonendaten::getVornameProperty);
    requireModifiablePropertyInstance(searchParametersMitPersonendaten, "GeschlechtProperty", searchParametersMitPersonendaten::getGeschlechtProperty);
    requireModifiablePropertyInstance(searchParametersMitPersonendaten, "GeburtsdatumProperty", searchParametersMitPersonendaten::getGeburtsdatumProperty);

    addPersonendatenProperties(formBuilder, searchParametersMitPersonendaten.getFamiliennameProperty(), searchParametersMitPersonendaten.getVornameProperty(),
        searchParametersMitPersonendaten.getGeschlechtProperty(), searchParametersMitPersonendaten.getGeburtsdatumProperty());
  }

  public void addPersonendatenProperties(FormBuilder formBuilder, Property ordnungsmerkmalProperty, Property familiennameProperty, Property vornameProperty, Property geschlechtProperty,
      Property geburtsdatumProperty) {
    // NOTE ELECT-4928, dass Wildcards nicht unterstützt werden sollen.
    formBuilder.addProperty(ordnungsmerkmalProperty).withRequired(false);

    addPersonendatenProperties(formBuilder, familiennameProperty, vornameProperty, geschlechtProperty, geburtsdatumProperty);
  }

  public void addPersonendatenProperties(FormBuilder formBuilder, Property familiennameProperty, Property vornameProperty, Property geschlechtProperty, Property geburtsdatumProperty) {
    String wildcardTooltip = getWildcardTooltip();

    formBuilder.addProperty(familiennameProperty) //
        .withRequired(false) //
        .withTooltip(wildcardTooltip);

    // NOTE ELECTMUC-1383, dass 'Rufname' und 'Vornamen' keine einzelnen Filterkriterien sein sollen.
    formBuilder.addProperty(vornameProperty) //
        .withRequired(false) //
        .withTooltip(wildcardTooltip) //
        .withLabel(getMessage(SearchParametersMitPersonendatenNamen.MESSAGE_KEY_VORNAME_EINZAHL));

    formBuilder.addProperty(geschlechtProperty) //
        .withRequired(false);

    formBuilder.addProperty(geburtsdatumProperty) //
        .withRequired(false) //
        .withConverter(new AutoFormatDateTimeConverter(true)); // ELECTMUC-2429
  }

  public String getWildcardTooltip() {
    return getMessage(AbstractSearchParameters.WILDCARD_TOOLTIP_MSG_KEY);
  }

  private void requireModifiablePropertyInstance(SearchParametersMitPersonendaten searchParametersMitPersonendaten, String propertyName, Supplier< ? > propertyGetter) {
    Object propertyA1 = propertyGetter.get();
    Object propertyA2 = propertyGetter.get();

    if (!Objects.equals(propertyA1, propertyA2)) {
      // NOTE ELECT-6919, dass solche Properties nach Aufruf der Methode nicht nochmals per FormBuilder#selectProperty gefunden und verändert werden können!
      LOG.warn("FAILED to find modifiable search parameter property [searchParameters = {}, property = {}]", searchParametersMitPersonendaten.getClass().getSimpleName(), propertyName);
    }
  }
}
