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

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.faces.convert.Converter;
import javax.faces.convert.EnumConverter;

import de.ivu.elect.business.konfiguration.entity.CustomParameter;
import de.ivu.elect.business.konfiguration.entity.CustomParameterFilter;
import de.ivu.elect.business.konfiguration.entity.CustomParameterTemplate;
import de.ivu.elect.jee.cdi.BeanManagerUtil;
import de.ivu.elect.jee.faces.FacesMessageUtil;

public class CustomParameterSelectOneMenuEnumProperty extends AbstractCustomParameterSelectOneMenuProperty<Enum< ? >> {

  private final Class< ? extends Enum< ? >> enumClass;

  public CustomParameterSelectOneMenuEnumProperty(CustomParameter<? extends CustomParameterTemplate> parameter) {
    super(parameter, x -> () -> getWertEnumValues(parameter));

    this.enumClass = getTemplate().getWertEnumClass();
  }

  private static List<Enum<?>> getWertEnumValues(CustomParameter<? extends CustomParameterTemplate> parameter) {
    Optional<Class<? extends Enum<?>>> wertEnumClass = parameter.getWertEnumClass();
    if (wertEnumClass.isPresent()) {
      List<Enum<?>> enums = CustomParameterTemplate.allEnumValues(wertEnumClass.get());

      Optional<? extends CustomParameterTemplate> template = parameter.getTemplate();
      if (template.isPresent()) {
        Class<? extends CustomParameterFilter<? extends CustomParameter<? extends CustomParameterTemplate>, ? extends Enum<?>>> filter = template.get()
            .getFilter();
        if (filter == null) {
          return enums;
        }
        CustomParameterFilter filterInstance = BeanManagerUtil.getBeanByClass(filter);
        return filterInstance.filter(parameter, enums);
      }

    }

    return Collections.emptyList();
  }

  public Class< ? extends Enum< ? >> getPropertyEnumClass() {
    return enumClass;
  }

  @Override
  public boolean hasNoSelectionItem() {
    return true; // Bei Filtern wichtig, damit nicht ein willkürliches erstes Element ausgewählt ist
  }

  @Override
  public boolean isRequired() {
    return true; // Enums sind immer @NotNull => required
  }

  @Override
  public Enum< ? > getValue() {
    return getParameter().getWertEnumValue();
  }

  @Override
  public void setValue(Enum< ? > value) {
    getParameter().setWertEnumValue(value);
  }

  @Override
  public String getItemLabel(Enum< ? > value) {
    return getMessage(FacesMessageUtil.getEnumMessageKey(value));
  }

  @Override
  public Converter getDefaultConverter() {
    return new EnumConverter(getPropertyEnumClass());
  }
}
