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

import static java.util.Objects.isNull;

import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;


import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.presentation.LambdaEntitySelectOneMenuProperty;
import de.ivu.elect.presentation.gruppe.form.GruppeSearchProperty;

public class KandidaturSearchProperty extends LambdaEntitySelectOneMenuProperty<Kandidatur> {

  private final GruppeSearchProperty<PolitischeGruppe> politischeGruppeSearchProperty;

  private final Function<Gruppe, List<Kandidatur>> kandidaturenByGruppeFinder;

  public KandidaturSearchProperty(GruppeSearchProperty<PolitischeGruppe> politischeGruppeSearchProperty,
      Function<Gruppe, List<Kandidatur>> kandidaturenByGruppeFinder, Consumer<Kandidatur> setter,
      Supplier<Kandidatur> getter, Function<Kandidatur, String> labeler, String msgKey, boolean required,
      boolean hasNoSelectionItem) {

    super(filterKandidaturenByGruppe(kandidaturenByGruppeFinder, politischeGruppeSearchProperty.getValue()), setter,
        getter, labeler, msgKey, required, hasNoSelectionItem);

    this.politischeGruppeSearchProperty = politischeGruppeSearchProperty;
    this.kandidaturenByGruppeFinder = kandidaturenByGruppeFinder;

    appendObservedPropertyValueChangedConsumer(property -> {
      if (property.equals(this.politischeGruppeSearchProperty)) {
        getValues().clear();
        getValues().addAll(filterKandidaturenByGruppe(kandidaturenByGruppeFinder, this.politischeGruppeSearchProperty.getValue()));
      }
    });
  }

  private static List<Kandidatur> filterKandidaturenByGruppe(
      Function<Gruppe, List<Kandidatur>> kandidaturenByGruppeFinder, Gruppe gruppe) {
    if (isNull(gruppe)) {
      return Collections.emptyList();
    }
    return kandidaturenByGruppeFinder.apply(gruppe);
  }

  public void updateValues() {
    PolitischeGruppe politischeGruppeSelektiert = politischeGruppeSearchProperty.getValue();

    List<Kandidatur> valuesNeu = kandidaturenByGruppeFinder.apply(politischeGruppeSelektiert);

    if (!getValues().equals(valuesNeu)) {
      getValues().clear();
      getValues().addAll(valuesNeu);
    }
  }
}
