
package de.ivu.elect.presentation.veranstaltung;

import javax.annotation.Nullable;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;
import javax.inject.Named;

import de.ivu.elect.business.gebietsbaum.boundary.GebietSelectChangeEvent;
import de.ivu.elect.business.person.boundary.PersonendatenConversationSelect;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.veranstaltung.boundary.VeranstaltungSearchMode;
import de.ivu.elect.business.veranstaltung.boundary.VeranstaltungSearchParameters;
import de.ivu.elect.business.veranstaltung.entity.TeilnahmeConstants;
import de.ivu.elect.business.veranstaltung.entity.Veranstaltung;
import de.ivu.elect.jee.entity.EagerLoadingCollector;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.ReadOnlyBooleanProperty;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.jee.presentation.search.AbstractSearchParameters;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;
import de.ivu.elect.presentation.security.AbstractGebietSecurityFilter;
import de.ivu.elect.presentation.veranstaltung.menu.VeranstaltungDisabledPruefer;
import de.ivu.elect.presentation.veranstaltung.table.VeranstaltungColumnBuilder;
import org.apache.deltaspike.core.api.scope.ViewAccessScoped;

@ViewAccessScoped
@OnlineHilfeId("375")
@Named(AbstractVeranstaltungSearchView.COMPONENT_NAME)
@View(viewId = AbstractVeranstaltungSearchView.VIEW_ID, useCase = UseCasePermission.VERANSTALTUNG_SEARCH)
public class VeranstaltungSearchView extends AbstractVeranstaltungSearchView {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient PersonendatenConversationSelect personendatenSelect;

  @Inject
  private transient VeranstaltungDisabledPruefer veranstaltungDisabledPruefer;

  @Inject
  private transient VeranstaltungColumnBuilder veranstaltungColumnBuilder;

  public VeranstaltungSearchView() {
    super();
  }

  @Nullable
  @PreConditionCheck
  public String checkCondition() {
    if (veranstaltungDisabledPruefer.isDisabled()) {
      return getStartViewId();
    }

    return null;
  }

  @Override
  protected AbstractGebietSecurityFilter<Veranstaltung> getGebietSecurityFilter() {
    return AbstractGebietSecurityFilter.createEntityMitGebietSecurityFilter(getEinsehenGebietSecurity());
  }

  public boolean isSearchByDefault() {
    // NOTE ELECT-7519, dass der Zustand "Standardsuche" keine vorbelegten Entitäten voraussetzt!
    return getSearchParameters().isSearchByDefault() && !isAnySearchByEntitySelected();
  }

  public void initSearchByDefault() {
    resetSearchBy(VeranstaltungSearchMode.SEARCH_BY_DEFAULT);
  }

  public void initSearchByPersonendaten(Personendaten personendaten) {
    resetSearchBy(VeranstaltungSearchMode.SEARCH_BY_PERSONENDATEN);

    personendatenSelect.setEntity(personendaten);
  }

  private void resetSearchBy(VeranstaltungSearchMode wahlhelferSearchMode) {
    clearSelectedSearchByEntities();

    resetSearchResult();
    reset();

    getSearchParameters().setSearchMode(wahlhelferSearchMode);
  }

  @Override
  public EagerLoadingCollector<Veranstaltung> getEagerLoadingCollector() {
    EagerLoadingCollector<Veranstaltung> eagerLoadingCollector = super.getEagerLoadingCollector();
    veranstaltungColumnBuilder.collectEagerLoadings(eagerLoadingCollector);
    return eagerLoadingCollector;
  }

  public String getGebietName() {
    return getSelectedGebietNameFormatted();
  }

  public void onGebietSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) GebietSelectChangeEvent event) {
    resetSearchResult();
  }

  public boolean isBtnBenachrichtigenRendered() {
    return hasPermission(UseCasePermission.VERANSTALTUNG_DOKUMENT_ERZEUGEN);
  }

  public boolean isBtnBenachrichtigenDisabled() {
    return isEmptySearchResultDisplayed();
  }

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

    // NOTE, dass die Reihenfolge wichtig ist!!!
    searchParameters.setWahltermin(getSelectedWahltermin());
    searchParameters.setWahl(getSelectedWahl());
    searchParameters.setGebiet(getSelectedGebiet());
  }

  /**
   * @deprecated To be removed...
   * @see VeranstaltungSearchView#initSearchParametersByContext
   */
  @Deprecated
  @Override
  public void presetSearchParameters() {
    // To be removed...
  }

  @Override
  public VeranstaltungSearchParameters getSearchParameters() {
    VeranstaltungSearchParameters searchParameters = super.getSearchParameters();

    if (isPersonendatenSelected()) {
      searchParameters.setVorgegebenePersonendaten(getSelectedPersonendaten());
    }

    return searchParameters;
  }

  @Override
  public void addProperties(FormBuilder formBuilder) {
    String wildcardTooltip = getMessage(AbstractSearchParameters.WILDCARD_TOOLTIP_MSG_KEY);

    formBuilder.addProperty(searchParameters.getVeranstaltungArtProperty());
    formBuilder.addProperty(searchParameters.getSchulungArtProperty());
    formBuilder.addProperty(searchParameters.getVeranstaltungStatusProperty());
    formBuilder.addProperty(searchParameters.getBezeichnungProperty()).withTooltip(wildcardTooltip);
    formBuilder.addProperty(searchParameters.getBemerkungProperty()).withTooltip(wildcardTooltip);

    formBuilder.addSeparator(TeilnahmeConstants.MESSAGE_KEY_PERSONENDATEN_ID_EINZAHL);

    boolean vorgegebenerTeilnehmer = searchParameters.hasVorgegebenePersonendaten();

    if (vorgegebenerTeilnehmer) {
      formBuilder.addProperty(new ReadOnlyBooleanProperty(getMessage("veranstaltung.search.teilnehmer.uebernommen"), true));
    }

    formBuilder.addProperty(searchParameters.getFamiliennameProperty()).withTooltip(wildcardTooltip).withReadonly(vorgegebenerTeilnehmer);
    formBuilder.addProperty(searchParameters.getVornameProperty()).withTooltip(wildcardTooltip).withReadonly(vorgegebenerTeilnehmer);
  }

  @Override
  public boolean isBtnGoBackRendered() {
    return isAnySearchByEntitySelected();
  }

  @Nullable
  @Override
  @Redirect
  public String goBack() {
    clearSelectedSearchByEntities();

    return super.goBack();
  }

  private boolean isAnySearchByEntitySelected() {
    return isPersonendatenSelected();
  }

  private void clearSelectedSearchByEntities() {
    personendatenSelect.clearEntity();
  }

  private boolean isPersonendatenSelected() {
    return personendatenSelect.isSelected();
  }

  private Personendaten getSelectedPersonendaten() {
    return personendatenSelect.getEntity();
  }
}
