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

import de.ivu.elect.business.CurrentCustomer;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.security.control.NlElectExtendedUseCasePermissionFilter;
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;
import org.apache.commons.lang3.StringUtils;
import org.apache.deltaspike.core.api.scope.ConversationGroup;

import javax.inject.Inject;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public abstract class AbstractNlWahlphaseSchrittMenuItem extends AbstractSchrittMenuItem {

  private static final long serialVersionUID = 1L;

  @Inject
  protected transient CurrentCustomer currentCustomer;

  @Inject
  private transient WahlSessionSelect wahlSessionSelect;

  @Inject
  private transient NlWahlprozess nlWahlprozess;

  @Inject
  private transient WahlExtendedDAO wahlExtendedDAO;

  @Inject
  protected transient StartViewResolver startViewResolver;

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


  protected abstract NlWahlPhase getZielWahlPhase();

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

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

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

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

  protected abstract boolean isPhaseDarfAktivWerdenInternal();

  @Override
  public String doActionInternal() {
    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();
  }

  @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 String getTitle() {
    return getMessage(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());
  }

}
