
package de.ivu.elect.presentation.wahlvorschlagsperson;

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

import java.util.List;

import javax.inject.Inject;

import de.ivu.elect.business.kandidatur.boundary.KandidaturConversationSelect;
import de.ivu.elect.business.person.boundary.SearchParametersMitOrdnungsmerkmal;
import de.ivu.elect.business.person.boundary.SearchParametersMitPersonendaten;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelect;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.business.wahlvorschlagsperson.boundary.WahlvorschlagsPersonConversationSelect;
import de.ivu.elect.business.wahlvorschlagsperson.boundary.WahlvorschlagsPersonPoolSearch;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPerson;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPersonPoolSearchResultEntry;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPersonTyp;
import de.ivu.elect.jee.entity.EagerLoadingCollector;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.personenregister.AbstractPersonenregisterPersonendatenSelectionView;
import de.ivu.elect.presentation.personenregister.AbstractPersonenregisterPersonendatenSelectionViewCreateViewHelper;
import de.ivu.elect.presentation.wahlvorschlagsperson.table.WahlvorschlagsPersonPoolSearchResultEntryColumnBuilder;

public abstract class AbstractWahlvorschlagsPersonPersonenregisterPersonendatenSelectionView extends AbstractPersonenregisterPersonendatenSelectionView<WahlvorschlagsPerson> {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahlSessionSelect wahlSelect;

  @Inject
  private transient WahlvorschlagsPersonPoolSearch wahlvorschlagsPersonPoolSearch;

  @Inject
  private transient WahlvorschlagsPersonConversationSelect wahlvorschlagsPersonPoolPersonendatenSelect;

  @Inject
  private transient WahlvorschlagsPersonPoolSearchResultEntryColumnBuilder wahlvorschlagsPersonPoolSearchResultEntryColumnBuilder;

  private List<WahlvorschlagsPersonPoolSearchResultEntry> wahlvorschlagsPersonPoolSearchResult;

  private WahlvorschlagsPersonPoolSearchResultEntry wahlvorschlagsPersonPoolSearchResultSelection;

  public AbstractWahlvorschlagsPersonPersonenregisterPersonendatenSelectionView() {
    super();
  }

  protected abstract AbstractWahlvorschlagspersonCreateViewHelper getWahlvorschlagspersonCreateViewHelper();

  @Override
  protected AbstractPersonenregisterPersonendatenSelectionViewCreateViewHelper<WahlvorschlagsPerson> getCreateViewHelper() {
    return getWahlvorschlagspersonCreateViewHelper();
  }

  public String getWahlvorschlagKennwort() {
    return getWahlvorschlagspersonCreateViewHelper().getWahlvorschlagKennwort();
  }

  private WahlvorschlagsPersonTyp getWahlvorschlagsPersonTypSelected() {
    return getWahlvorschlagspersonCreateViewHelper().getInitialerWahlvorschlagsPersonTyp(getWahlvorschlagspersonCreateViewHelper().isIndividuelleWahlvorschlagsPerson());
  }

  private boolean isWahlSelected() {
    return wahlSelect.isSelected();
  }

  private Wahl getWahl() {
    return wahlSelect.getEntity();
  }

  @Override
  protected Wahltermin getWahltermin() {
    if (isWahlSelected()) {
      return getWahl().getWahltermin();
    }

    return null;
  }

  public List<WahlvorschlagsPersonPoolSearchResultEntry> getWahlvorschlagsPersonPoolSearchResult() {
    return wahlvorschlagsPersonPoolSearchResult;
  }

  public void setWahlvorschlagsPersonPoolSearchResult(List<WahlvorschlagsPersonPoolSearchResultEntry> wahlvorschlagsPersonPoolSearchResult) {
    this.wahlvorschlagsPersonPoolSearchResult = wahlvorschlagsPersonPoolSearchResult;
  }

  public WahlvorschlagsPersonPoolSearchResultEntry getWahlvorschlagsPersonPoolSearchResultSelection() {
    return wahlvorschlagsPersonPoolSearchResultSelection;
  }

  public void setWahlvorschlagsPersonPoolSearchResultSelection(WahlvorschlagsPersonPoolSearchResultEntry wahlvorschlagsPersonPoolSearchResultSelection) {
    this.wahlvorschlagsPersonPoolSearchResultSelection = wahlvorschlagsPersonPoolSearchResultSelection;
  }

  @Override
  public boolean isSearchByPersonendatenSupported() { // ELECT-8462
    return super.isSearchByPersonendatenSupported() || isSearchWahlvorschlagsPersonPoolSupported();
  }

  private boolean isSearchWahlvorschlagsPersonPoolSupported() {
    return isBtnSearchWahlvorschlagsPersonPoolRendered() && !isBtnSearchWahlvorschlagsPersonPoolDisabled();
  }

  public boolean isBtnSearchWahlvorschlagsPersonPoolRendered() {
    return hasPermission(UseCasePermission.WAHLVORSCHLAGS_PERSON_SEARCH_ALL); // ELECT-10614
  }

  public boolean isBtnSearchWahlvorschlagsPersonPoolDisabled() {
    return false;
  }

  @Redirect
  public String searchWahlvorschlagsPersonPool() {
    resetSearch();

    SearchParametersMitPersonendaten searchByPersonendatenSearchParameters = getSearchByPersonendatenSearchParameters();
    boolean searchByPersonendatenRequested = isNotBlank(searchByPersonendatenSearchParameters.getFamilienname());

    SearchParametersMitOrdnungsmerkmal searchByOrdnungsmerkmalSearchParameters = getSearchByOrdnungsmerkmalSearchParameters();
    boolean searchByOrdnungsmerkmalRequested = isNotBlank(searchByOrdnungsmerkmalSearchParameters.getOrdnungsmerkmal());

    requireNonAmbiguousSearchParameters(searchByPersonendatenRequested, searchByOrdnungsmerkmalRequested);

    EagerLoadingCollector<WahlvorschlagsPersonPoolSearchResultEntry> eagerLoadingCollector = EagerLoadingCollector.create();
    wahlvorschlagsPersonPoolSearchResultEntryColumnBuilder.collectEagerLoadings(eagerLoadingCollector);

    wahlvorschlagsPersonPoolSearchResult = wahlvorschlagsPersonPoolSearch.getSearchResult(getWahl(), searchByPersonendatenSearchParameters, searchByOrdnungsmerkmalSearchParameters,
        eagerLoadingCollector);

    if (wahlvorschlagsPersonPoolSearchResult.isEmpty()) {
      addWarningMessage("entity.mit.personendaten.selection.search.result.empty.message");
    }

    for (WahlvorschlagsPersonPoolSearchResultEntry wahlvorschlagsPersonPoolSearchResultEntry : wahlvorschlagsPersonPoolSearchResult) {
      // NOTE, dass diese Information für die Anzeige der Einträge im Action-Menü per Zeile benötigt wird!
      wahlvorschlagsPersonPoolSearchResultEntry.setWahlvorschlagsPersonTypSelected(getWahlvorschlagsPersonTypSelected());
    }

    return getViewId();
  }

  @Override
  protected void resetSearch() {
    super.resetSearch();

    wahlvorschlagsPersonPoolSearchResult = null;
    wahlvorschlagsPersonPoolSearchResultSelection = null;

    wahlvorschlagsPersonPoolPersonendatenSelect.clearEntity();
  }
}
