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

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

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import javax.faces.convert.Converter;

import de.ivu.elect.jee.presentation.dynamicform.AbstractSelectOneMenuProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;

public class AbstractEntschaedigungsartKriteriumProperty extends AbstractSelectOneMenuProperty<String> {

  private final AbstractStringProperty kriteriumProperty;

  private final Map<String, EntschaedigungsartKriterium> kriteriumPerTechnicalName;

  private Function<EntschaedigungsartKriterium, String> itemLabeler = null;

  public AbstractEntschaedigungsartKriteriumProperty(AbstractStringProperty kriteriumProperty, List< ? extends EntschaedigungsartKriterium> values) {
    super();

    this.kriteriumProperty = kriteriumProperty;
    this.kriteriumPerTechnicalName = toSortedMap(values);
  }

  private Map<String, EntschaedigungsartKriterium> toSortedMap(List< ? extends EntschaedigungsartKriterium> values) {
    // Reihenfolge von one und another getauscht -> "W"ahlhelfer als erstes in der Liste...
    Comparator<EntschaedigungsartKriterium> valuesComparator = (one, another) -> another.getDisplayName(getMessages()).compareTo(one.getDisplayName(getMessages()));

    Map<String, EntschaedigungsartKriterium> result = new LinkedHashMap<>();
    values.stream().sorted(valuesComparator).forEach(value -> result.put(value.getTechnicalName(), value));

    return result;
  }

  @Override
  public boolean getDefaultRequired() {
    return kriteriumProperty.getDefaultRequired();
  }

  @Override
  public String getValue() {
    return kriteriumProperty.getValue();
  }

  @Override
  public void setValue(String value) {
    kriteriumProperty.setValue(value);
  }

  @Override
  public List<String> getValues() {
    return new ArrayList<>(kriteriumPerTechnicalName.keySet());
  }

  @Override
  public String getDefaultLabel() {
    return kriteriumProperty.getDefaultLabel();
  }

  public void setItemLabeler(Function<EntschaedigungsartKriterium, String> itemLabeler) {
    this.itemLabeler = itemLabeler;
  }

  @Override
  public String getItemLabel(String item) {
    if (isNotBlank(item) && kriteriumPerTechnicalName.containsKey(item)) {
      EntschaedigungsartKriterium entschaedigungsartKriterium = kriteriumPerTechnicalName.get(item);

      if (itemLabeler == null) {
        return entschaedigungsartKriterium.getDisplayName(getMessages());
      }

      return itemLabeler.apply(entschaedigungsartKriterium);
    }

    return "";
  }

  @Override
  public Converter getDefaultConverter() {
    return kriteriumProperty.getDefaultConverter();
  }
}
