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

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

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

import de.ivu.elect.business.anschrift.entity.AbstractAnschrift;
import de.ivu.elect.business.geodata.entity.GeodataPlzUK;
import de.ivu.elect.jee.presentation.dynamicform.AbstractAutoCompleteOptionsProvider;

public class GeodataOrtGeodataPlzAutoCompleteOptionsProvider extends AbstractAutoCompleteOptionsProvider<GeodataPlzUK> {

  private static final long serialVersionUID = 1L;

  private static final Converter CONVERTER = new GeodataPlzConverter();

  private final List<GeodataPlzUK> options;

  public GeodataOrtGeodataPlzAutoCompleteOptionsProvider() {
    this(createDefaultGeodataPostleitzahlen());
  }

  public GeodataOrtGeodataPlzAutoCompleteOptionsProvider(List<GeodataPlzUK> optionsSorted) {
    super();

    this.options = optionsSorted;
  }

  @Override
  public GeodataPlzUK tryGetOptionByQuery(String query) {
    return new GeodataPlzUK(query);
  }

  @Override
  protected List<GeodataPlzUK> getOptions() {
    return options;
  }

  @Override
  protected Predicate< ? super GeodataPlzUK> matchesQuery(String query) {
    return geodataPostleitzahl -> startsWithIgnoreCase(geodataPostleitzahl.getPlz(), query);
  }

  @Override
  public Converter getConverter() {
    return CONVERTER;
  }

  private static List<GeodataPlzUK> createDefaultGeodataPostleitzahlen() {
    List<GeodataPlzUK> result = new ArrayList<>();

    for (int i = 0; i < 100000; i++) {
      result.add(new GeodataPlzUK(leftPad(String.valueOf(i), AbstractAnschrift.PLZ_DEFAULT_LENGTH, '0')));
    }

    return result;
  }

  private static final class GeodataPlzConverter implements Converter {

    public GeodataPlzConverter() {
      super();
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
      if (value instanceof GeodataPlzUK) {
        return ((GeodataPlzUK) value).getPlz();
      }

      return "";
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
      if (isNotBlank(value)) {
        return new GeodataPlzUK(value);
      }

      return null;
    }
  }
}
