
package de.ivu.elect.presentation.wahl.menu;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.deltaspike.core.api.scope.ConversationGroup;

import de.ivu.elect.business.CurrentCustomer;
import de.ivu.elect.business.security.Customer;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.security.control.NlElectExtendedUseCasePermissionFilter;
import de.ivu.elect.business.system.boundary.NlSpecialBackgroundServiceRunning;
import de.ivu.elect.business.wahl.boundary.NlWahlprozess;
import de.ivu.elect.business.wahl.boundary.WahlExtendedDAO;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelect;
import de.ivu.elect.business.wahl.entity.NlWahlCustomData;
import de.ivu.elect.business.wahl.entity.NlWahlPhase;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.faces.FacesContextUtil;
import de.ivu.elect.jee.presentation.security.StartViewResolver;
import de.ivu.elect.presentation.exchange.SupportedFileFormatErmittler;
import de.ivu.elect.presentation.menu.AbstractSchrittMenuItem;
import de.ivu.elect.presentation.security.AbstractGebietSecurity;

public abstract class AbstractNlWahlphaseSchrittMenuItem extends AbstractSchrittMenuItem {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient CurrentCustomer currentCustomer;

  @Inject
  private transient WahlSessionSelect wahlSessionSelect;

  @Inject
  private transient NlWahlprozess nlWahlprozess;

  @Inject
  private transient WahlExtendedDAO wahlExtendedDAO;

  @Inject
  private transient StartViewResolver startViewResolver;

  @Inject
  @ConversationGroup(SupportedFileFormatErmittler.class)
  private transient SupportedFileFormatErmittler supportedFileFormatErmittler;

  @Inject
  private transient NlSpecialBackgroundServiceRunning nlSpecialBackgroundServiceRunning;

  protected AbstractNlWahlphaseSchrittMenuItem() {
    super();
  }

  protected abstract NlWahlPhase getZielWahlPhase();

  @Override
  protected boolean isDisabledInternal() {
    return getZielWahlPhase().equals(getAktuellePhase()) || !isUebergangMoeglich() || !isPhaseDarfAktivWerden();
  }

  protected boolean isHintergrundProzessLaeuft() {
    return nlSpecialBackgroundServiceRunning.isSomethingRunning();
  }

  protected boolean isUebergangMoeglich() {
    return getAktuellePhase().getNachfolger().contains(getZielWahlPhase()) || getAktuellePhase().getVorgaenger().contains(getZielWahlPhase());
  }

  protected boolean isPhaseUeberhauptMoeglich() {
    return getZielWahlPhase().isAccept(getCustomer(), getSelectedWahl());
  }

  private boolean isPhaseDarfAktivWerden() {
    //    if (DevelopmentStore.isDevelopmentStage()) {
    //      return true;
    //    }

    if (isHintergrundProzessLaeuft()) {
      addWarnMessage("nl.hintergrundprozess.laeuft.noch.warnung");

      return false;
    }

    return isPhaseDarfAktivWerdenInternal();
  }

  protected abstract boolean isPhaseDarfAktivWerdenInternal();

  @Override
  public String doActionInternal() {
    nlSpecialBackgroundServiceRunning.waitForBackgroundService(); // ELECTVAPP-1721

    if (!isActionPossible()) {
      addWarnMessage("wahl.wahlphase.wachseln.nicht.moeglich");

      return FacesContextUtil.getCurrentViewId();
    }

    return doActionInternalAfterCheck();
  }

  protected String doActionInternalAfterCheck() {
    Wahl selectedWahl = getSelectedWahl();

    if (selectedWahl != null) {
      boolean wasBefore = isBefore();

      nlWahlprozess.setzeWahlPhase(selectedWahl, getZielWahlPhase());

      wahlExtendedDAO.clear();
      NlElectExtendedUseCasePermissionFilter.resetCache(); // Ist von Wahlphase abhaengig
      supportedFileFormatErmittler.reset();

      addInfoMessage("wahl.wahlphase.gewwechselt", getMessage(getZielWahlPhase()));

      if (!wasBefore) {
        return startViewResolver.getStartViewId(); // mitunter springt man beim Vorwärts gehen "irgendwo" hin
      }

    }
    return FacesContextUtil.getCurrentViewId();
  }

  protected boolean isActionPossible() {
    return !isDisabledInternal();
  }

  @Override
  public boolean isRendered() {
    return getSelectedWahl() != null && hasUseCasePermission(UseCasePermission.CUSTOMER_5) && isPhaseUeberhauptMoeglich();
  }

  protected NlWahlPhase getAktuellePhase() {
    Wahl selectedWahl = getSelectedWahl();

    if (selectedWahl == null) {
      return NlWahlPhase.NICHT_GESETZT;
    }

    return selectedWahl.getCustomData(NlWahlCustomData.class).getNlWahlPhase();
  }

  protected Wahl getSelectedWahl() {
    return wahlSessionSelect.getEntity();
  }

  @Override
  protected AbstractGebietSecurity getGebietSecurity() {
    return KEINE_GEBIET_SECURITY;
  }

  @Override
  protected boolean isTopicActiveInternal() {
    return getAktuellePhase().equals(getZielWahlPhase());
  }

  @Override
  public final String getTitle() {
    return getMessage(getTitleMsgKey(getSelectedWahl()));
  }

  protected String getTitleMsgKey(Wahl wahl) {
    return getLabelKey() + ".title";
  }

  @Override
  protected boolean isBefore() {
    return getAktuellePhase().getVorgaenger().contains(getZielWahlPhase());
  }

  public List<String> getDialogTemplates() {
    return getPosssibleDialogs().stream().filter(StringUtils::isNotBlank).map(posssibleDialog -> "/WEB-INF/templates/wahl/" + posssibleDialog + ".xhtml").collect(Collectors.toList());
  }

  protected List<String> getPosssibleDialogs() {
    return Collections.singletonList(getDialogName());
  }

  protected Customer getCustomer() {
    return currentCustomer.getCustomer();
  }
}
