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

import static java.util.stream.Collectors.joining;

import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.gebietsbaum.boundary.GebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.kandidatur.entity.KandidaturStatus;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.kandidatur.entity.NlKandidatur;
import de.ivu.elect.business.kandidatur.entity.NlListenkandidatur;
import de.ivu.elect.business.pruefung.boundary.ZulassungPruefer;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.entity.NlWahlart;
import de.ivu.elect.business.wahlrechtspruefung.entity.NlPruefkriteriumAuswirkung;
import de.ivu.elect.jee.faces.FacesContextUtil;
import de.ivu.elect.presentation.wahl.CurrentWahlZulassungspruefungExtended;
import de.ivu.elect.presentation.wahlvorschlag.NlListeStelInformationChangeEvent;

@Named(NlListenkandidaturZulassungAblehnenMitBemerkungAction.COMPONENT_NAME) // ELECT-10224, cf. NlListeZulassungAblehnenMitBemerkungAction!
public class NlListenkandidaturZulassungAblehnenMitBemerkungAction extends AbstractListenkandidaturZulassungAction {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "nlListenkandidaturZulassungAblehnenMitBemerkungAction";

  public static final String DIALOG_TEMPLATE_PATH = "/WEB-INF/templates/kandidatur/listenkandidatur-zulassung-ablehnen-mit-bemerkung-dialog.xhtml";

  @Inject
  private transient GebietSessionSelect gebietSessionSelect;

  @Inject
  private transient ListenkandidaturZulassungAblehnenAction listenkandidaturZulassungAblehnenAction;

  @Inject
  private transient NlListeStelInformationChangeEvent nlListeStelInformationChangeEvent;

  public NlListenkandidaturZulassungAblehnenMitBemerkungAction() {
    super();
  }

  @Override
  public UseCasePermission getRequiredPermission() {
    return listenkandidaturZulassungAblehnenAction.getRequiredPermission();
  }

  @Override
  public boolean isDisabledInternal(Listenkandidatur listenkandidatur, CurrentWahlZulassungspruefungExtended currentWahlZulassungspruefung) {
    return listenkandidaturZulassungAblehnenAction.isDisabledInternal(listenkandidatur, currentWahlZulassungspruefung);
  }

  @Override
  protected KandidaturStatus getKandidaturStatus() {
    return listenkandidaturZulassungAblehnenAction.getKandidaturStatus();
  }

  @Override
  protected String doIt(@Nonnull Listenkandidatur template) {
    listenkandidaturConversationSelect.setEntity(template);

    Listenkandidatur listenkandidatur = listenkandidaturConversationSelect.getEntity();

    // ELECT-10750
    String kandidaturStatusBemerkung = new NlListenkandidatur(listenkandidatur).formatPruefungenZuBehebenLangtexteExcludingZulassungPrueferExtraInformation(getZulassungPruefer()).stream() //
        .filter(StringUtils::isNotBlank) //
        .collect(joining(NlKandidatur.ZULASSUNG_ABGELEHNT_BEGRUENDUNG_SEPARATOR));

    setKandidaturStatusBemerkung(kandidaturStatusBemerkung);

    return null; // Return to current page and display the dialog!
  }

  @Override
  public String getDialogName() {
    return "NlListenkandidaturZulassungAblehnenMitBemerkungConfirm";
  }

  public String getDialogHeader() {
    return getLocalizedLabel();
  }

  public String getDialogMessage() {
    return getMessage("listenkandidatur.search.action.nicht.zulassen.mit.bemerkung.confirm.message");
  }

  public void doActionConfirmedListe() {
    doActionConfirmed(NlPruefkriteriumAuswirkung.LISTE);
  }

  public boolean isConfirmRenderedListe() {
    return false;
  }

  public String getLabelConfirmedListe() {
    if (isWahlMitWahlkreisen()) {
      return getMessage("nl.listenkandidatur.nicht.zulassen.wahlkreis");
    }

    return getMessage("nl.listenkandidatur.nicht.zulassen.liste");
  }

  public void doActionConfirmedStel() {
    doActionConfirmed(NlPruefkriteriumAuswirkung.STEL);
  }

  public boolean isConfirmRenderedStel() {
    return false;
  }

  public String getLabelConfirmedStel() {
    return getMessage("nl.listenkandidatur.nicht.zulassen.stel");
  }

  public void doActionConfirmedGruppe() {
    doActionConfirmed(NlPruefkriteriumAuswirkung.GRUPPE);
  }

  public boolean isConfirmRenderedGruppe() {
    return false;
  }

  public String getLabelConfirmedGruppe() {
    return getMessage("nl.listenkandidatur.nicht.zulassen.gruppe");
  }

  public boolean isConfirmRenderedSave() {
    return true;
  }

  // NOTE, dass diese Methode in /nl-core-jar/src/main/resources/META-INF/contracts/custom/WEB-INF/templates/kandidatur/listenkandidatur-zulassung-ablehnen-mit-bemerkung-dialog.xhtml aufgerufen wird!
  public void doActionConfirmed() {
    Listenkandidatur listenkandidatur = listenkandidaturConversationSelect.getEntity();

    String outcome = doActionConfirmed(listenkandidatur);

    listenkandidaturConversationSelect.clearEntity();

    refreshViewOnNonBlankResult(listenkandidatur, FacesContextUtil.getCurrentViewId()/*  wichtig für de.ivu.elect.presentation.kandidatur.action.NlKandidaturDublettenAblehnenAction */);
  }

  // NOTE, dass diese Methode in /nl-core-jar/src/main/resources/META-INF/contracts/custom/WEB-INF/templates/kandidatur/listenkandidatur-zulassung-ablehnen-mit-bemerkung-dialog.xhtml aufgerufen wird!
  public void doActionConfirmed(NlPruefkriteriumAuswirkung nlPruefkriteriumAuswirkung) {
    Listenkandidatur listenkandidatur = listenkandidaturConversationSelect.getEntity();
    listenkandidatur.getTransientContext().put(NlPruefkriteriumAuswirkung.AUSWIRKUNG_CONTEXT_KEY, nlPruefkriteriumAuswirkung);

    String outcome = doActionConfirmed(listenkandidatur);

    listenkandidaturConversationSelect.clearEntity();

    nlListeStelInformationChangeEvent.sendEvent(); // ELECT-11675

    refreshViewOnNonBlankResult(listenkandidatur, FacesContextUtil.getCurrentViewId()/*  wichtig für de.ivu.elect.presentation.kandidatur.action.NlKandidaturDublettenAblehnenAction */);
  }

  private String doActionConfirmed(Listenkandidatur listenkandidatur) {
    if (listenkandidatur != null && isActionPossible(listenkandidatur)) {
      String kandidaturStatusBemerkung = getKandidaturStatusBemerkung();

      String outcome = listenkandidaturZulassungAblehnenAction.doIt(listenkandidatur, getKandidaturStatus(), kandidaturStatusBemerkung);

      NlListenkandidatur nlListenkandidatur = new NlListenkandidatur(listenkandidatur);
      nlListenkandidatur.setZulassungAbgelehntBegruendung(kandidaturStatusBemerkung);

      return outcome;
    }

    return FacesContextUtil.getCurrentViewId();
  }

  @Override
  public String getLabelKey() {
    return listenkandidaturZulassungAblehnenAction.getLabelKey();
  }

  private ZulassungPruefer getZulassungPruefer() {
    return getCurrentWahlZulassungspruefung().getZulassungPruefer();
  }

  private boolean isWahlMitWahlkreisen() {
    Gebiet gebiet = getSelectedGebiet();

    if (gebiet != null) {
      return NlWahlart.valueOf(gebiet.getWahl()).isWahlartMitWahlkreisen();
    }

    return true; // Bisheriger Standard...
  }

  protected Gebiet getSelectedGebiet() {
    return gebietSessionSelect.getEntity();
  }
}
