
package de.ivu.elect.jee.presentation.dynamicform;

import static java.util.Objects.isNull;

import java.util.List;

public abstract class AbstractSelectOneAutoCompleteProperty<T> extends AbstractAutoCompleteProperty<T, T> {

  private final boolean forceOptionSelection;

  public AbstractSelectOneAutoCompleteProperty(AbstractAutoCompleteOptionsProvider<T> optionsProvider) {
    super(optionsProvider);

    this.forceOptionSelection = optionsProvider instanceof AbstractAutoCompleteEnumOptionsProvider || optionsProvider instanceof AbstractAutoCompleteEntityOptionsProvider;
  }

  @Override
  protected boolean mustBeAccessableOnPageLoadByValue() {
    if (super.mustBeAccessableOnPageLoadByValue()) {
      return true;
    }

    return notAllEqual(getDefaultValue(), getValue());
  }

  @Override
  protected boolean hasDefaultValue() {
    return notNullOrBlank(getDefaultValue());
  }

  @Override
  public T getDefaultValue() {
    return null;
  }

  @Override
  public boolean hasValue() {
    return notNullOrBlank(getValue());
  }

  @Override
  public boolean isMultipleEnabled() {
    return false;
  }

  @Override
  public boolean isDropdownEnabled() {
    return isForceOptionSelection() && hasOptions();
  }

  @Override
  public boolean isCacheEnabled() {
    return isDropdownEnabled();
  }

  @Override
  protected boolean isForceOptionSelection() {
    return forceOptionSelection;
  }

  @Override
  public int getMaxOptionsSelectedCount() {
    return 1;
  }

  @Override
  protected T handleNonNullOptionByRecentQuery(T optionSelected, T optionByRecentQuery) {
    if (isOptionByRecentQueryOverridesOptionSelected(optionSelected, optionByRecentQuery)) {
      return optionByRecentQuery;
    }

    return optionSelected;
  }

  private boolean isOptionByRecentQueryOverridesOptionSelected(T optionSelected, T optionByRecentQuery) {
    if (isNull(optionSelected) || optionSelected.equals(optionByRecentQuery)) {
      return true;
    }

    List<T> optionsFilteredByRecentQuery = getOptionsFilteredInternal(getRecentQuery());

    return !optionsFilteredByRecentQuery.contains(optionSelected) && optionsFilteredByRecentQuery.contains(optionByRecentQuery);
  }
}
