
package de.ivu.elect.presentation.praesentation;

import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.PREASENTATIION_AUTOMATISCHEN_EXPORT_ANSTOSSEN;
import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.PREASENTATIION_ERFASSUNGSGEBIETE_PRO_WAHLGEBIET_NOTWENDIG;
import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.PREASENTATIION_ERFASSUNGSGEBIETE_ZURUECKHALTEN;
import static java.util.Arrays.asList;

import java.util.Arrays;

import javax.annotation.Nullable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.ergebnis.boundary.ErgebnisSessionSelect;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.internet.boundary.InternetPraesentationErmittler;
import de.ivu.elect.business.internet.boundary.PraesentationKonfigurieren;
import de.ivu.elect.business.internet.entity.PraesentationKonfiguration;
import de.ivu.elect.business.praesentation.entity.PraesentationAutomatischenExportAnstossen;
import de.ivu.elect.business.praesentation.entity.PraesentationBereitstellen;
import de.ivu.elect.business.praesentation.entity.PraesentationErfassungsgebieteZurueckhalten;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.security.control.ElectCommonPrincipal;
import de.ivu.elect.business.sitzberechnung.control.Sitzberechnungsalgorithmus;
import de.ivu.elect.business.sitzberechnung.control.SitzberechnungsalgorithmusFinder;
import de.ivu.elect.business.wahl.boundary.WahldurchfuehrungSessionSelect;
import de.ivu.elect.business.wahl.entity.WahlParameterExtendedLoader;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.presentation.dynamicform.AdvancedDynaFormModel;
import de.ivu.elect.jee.presentation.dynamicform.DynamicFormEditOrCreateView;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaLongProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaStringProperty;
import de.ivu.elect.jee.presentation.dynamicform.Property;
import de.ivu.elect.jee.presentation.dynamicform.ReadOnlyStringProperty;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.jee.presentation.security.StartViewResolver;
import de.ivu.elect.jee.presentation.view.AbstractView;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;

@OnlineHilfeId("294")
@RequestScoped
@Named(PraesentationKonfigurierenView.COMPONENT_NAME)
@View(viewId = PraesentationKonfigurierenView.VIEW_ID, useCase = UseCasePermission.PRAESENTATION_KONFIGURIEREN)
public class PraesentationKonfigurierenView extends AbstractView implements DynamicFormEditOrCreateView {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "praesentationKonfigurierenView";

  public static final String VIEW_ID = "/praesentation/praesentation-konfigurieren.xhtml";

  @Inject
  private transient ElectCommonPrincipal principal;

  @Inject
  private transient PraesentationExportieren praesentationExportieren;

  @Inject
  private transient PraesentationKonfigurieren praesentationKonfigurieren;

  @Inject
  private transient ErgebnisSessionSelect ergebnisSessionSelect;

  @Inject
  private transient WahldurchfuehrungSessionSelect wahldurchfuehrungSessionSelect;

  @Inject
  private transient WahlParameterExtendedLoader wahlParameterExtendedLoader;

  @Inject
  private transient StartViewResolver startViewResolver;

  @Inject
  private transient SitzberechnungsalgorithmusFinder sitzberechnungsalgorithmusFinder;

  @Inject
  private transient PraesentationKonfigurierenVorlageView praesentationKonfigurierenVorlageView;

  @Inject
  private transient PraesentationUrl praesentationUrl;

  @Inject
  private transient InternetPraesentationErmittler internetPraesentationErmittler;

  private PraesentationKonfiguration praesentationKonfiguration;

  private transient AdvancedDynaFormModel model = null;

  public PraesentationKonfigurierenView() {
    super();
  }

  @Nullable
  @PreConditionCheck
  public String checkCondition() {
    if (!wahldurchfuehrungSessionSelect.isSelected()) {
      addErrorMessage("wahl.selected.missing");

      return startViewResolver.getStartViewId();
    }

    return null;
  }

  public PraesentationKonfiguration getPraesentationKonfiguration() {
    if (praesentationKonfiguration == null) {
      praesentationKonfiguration = praesentationKonfigurieren.getPraesentationKonfiguration(getSelectedWahl());
    }

    return praesentationKonfiguration;
  }

  @Override
  public AdvancedDynaFormModel getModel() {
    if (model == null) {
      FormBuilder formBuilder = new FormBuilder();

      PraesentationKonfiguration praesentationKonfiguration = getPraesentationKonfiguration();

      formBuilder.addSeparator("presentation.konfigurieren.system.parameter");

      //      Property alsZipDateiAblegenProperty = praesentationKonfiguration.getAlsZipDateiAblegenProperty(getMessages());
      //      formBuilder.addProperty(alsZipDateiAblegenProperty);

      Property internetAktiviertProperty = praesentationKonfiguration.getInternetAktiviertProperty(getMessages());
      formBuilder.addProperty(internetAktiviertProperty).readonly();

      Property minimalePauseInSekundenZwischenZweiExportenProperty = praesentationKonfiguration.getMinimalePauseInSekundenZwischenZweiExportenProperty(getMessages());
      formBuilder.addProperty(minimalePauseInSekundenZwischenZweiExportenProperty).readonly();

      //      Property ausgabeverzeichnisProperty = praesentationKonfiguration.getAusgabeverzeichnisProperty(getMessages());
      //      formBuilder.addProperty(ausgabeverzeichnisProperty).readonly();

      formBuilder.addSeparator("presentation.konfigurieren.wahl.parameter");

      formBuilder.addProperty(new LambdaEnumProperty<>(getMessage("praesentation.status.diese.wahl.exportieren"), true, praesentationKonfiguration::setPraesentationBereitstellen,
          praesentationKonfiguration::getPraesentationBereitstellen, PraesentationBereitstellen.class, asList(PraesentationBereitstellen.values())));

      if (ergebnisSessionSelect.isSelected() && StringUtils.isNotBlank(praesentationKonfiguration.getAusgabeverzeichnis()) /* ELECT-8951 */ ) {
        formBuilder.addProperty(praesentationKonfiguration.getAusgabeverzeichnisInternetFinalProperty(getMessages(), ergebnisSessionSelect.getEntity())).readonly();
      }

      formBuilder
          .addProperty(new LambdaEnumProperty<>(messages.lokalisiere(PREASENTATIION_AUTOMATISCHEN_EXPORT_ANSTOSSEN), true, praesentationKonfiguration::setPraesentationAutomatischenExportAnstossen,
              praesentationKonfiguration::getPraesentationAutomatischenExportAnstossen, PraesentationAutomatischenExportAnstossen.class, asList(PraesentationAutomatischenExportAnstossen.values())));

      formBuilder.addProperty(new LambdaLongProperty(messages.lokalisiere(PREASENTATIION_ERFASSUNGSGEBIETE_PRO_WAHLGEBIET_NOTWENDIG), false,
          praesentationKonfiguration::setPraesentationErfassungsgebieteNotwendig, praesentationKonfiguration::getPraesentationErfassungsgebieteNotwendig, 0L, 100L, 3));

      formBuilder.addProperty(new LambdaEnumProperty<>(messages.lokalisiere(PREASENTATIION_ERFASSUNGSGEBIETE_ZURUECKHALTEN), true,
          praesentationKonfiguration::setPraesentationErfassungsgebieteZurueckhalten, praesentationKonfiguration::getPraesentationErfassungsgebieteZurueckhalten,
          PraesentationErfassungsgebieteZurueckhalten.class, asList(PraesentationErfassungsgebieteZurueckhalten.values())));

      // ELECT-7250
      formBuilder.addProperty(new ReadOnlyStringProperty(getMessage("presentation.konfigurieren.url.vollstaendig"), praesentationUrl.getPraesentationIndexUrl()));

      formBuilder.addProperty(
          new LambdaStringProperty(getMessage("praesentation.url.label"), false, praesentationKonfiguration::setPraesentationUrl, praesentationKonfiguration::getPraesentationUrl, 0, 1000));

      formBuilder.addProperty(praesentationKonfiguration.getDokumentVorlage().getProperties().getNameProperty()).readonly().withLabel(getMessage("praesentation.export.internet.vorlage"));

      model = formBuilder.createModel();
    }

    return model;
  }

  private boolean isGewaehlteWerdenMarkiert() {
    Wahldurchfuehrung wahldurchfuehrung = getSelectedWahl();
    Sitzberechnungsalgorithmus sitzberechnungsalgorithmus = getSitzberechnungsalgorithmus();

    return Arrays.stream(Ergebnisart.values()).anyMatch(ergebnisart -> sitzberechnungsalgorithmus.isMarkiertGewaehlte(wahlParameterExtendedLoader, wahldurchfuehrung, ergebnisart));
  }

  private boolean isSitzeWerdenVergeben() {
    return getSitzberechnungsalgorithmus().isVergibtSitze();
  }

  private Sitzberechnungsalgorithmus getSitzberechnungsalgorithmus() {
    return sitzberechnungsalgorithmusFinder.getSitzberechnungsalgorithmus(getSelectedWahl());
  }

  private Wahldurchfuehrung getSelectedWahl() {
    return wahldurchfuehrungSessionSelect.getEntity();
  }

  @Override
  public boolean isBtnSaveRendered() {
    return true;
  }

  @Override
  public String getBtnSaveLabel() {
    return getMessage("entity.edit.action.save");
  }

  @Override
  @Redirect
  public String save() {
    praesentationKonfigurieren.savePraesentationKonfiguration(getPraesentationKonfiguration(), praesentationKonfigurierenVorlageView.getUploadedFile());
    addInfoMessage("praesentation.konfiguration.save.success");
    praesentationKonfigurierenVorlageView.reset();
    return goBack(PraesentationStatusView.VIEW_ID);
  }

  @Override
  public boolean isBtnResetRendered() {
    return true;
  }

  @Override
  @Redirect
  public String reset() {
    model = null;
    praesentationKonfigurierenVorlageView.reset();
    return VIEW_ID;
  }

  @Override
  public boolean isBtnCancelRendered() {
    return true;
  }

  @Override
  @Redirect
  public String cancel() {
    return goBack(PraesentationStatusView.VIEW_ID);
  }

  public void exportiereInternetPraesentation() {
    praesentationExportieren.exportiereInternetPraesentation();
  }

  public boolean isButtonInternetExportierenRendered() {
    return false && principal.hasUseCasePermission(UseCasePermission.PRAESENTATION_EXPORTIEREN) && ergebnisSessionSelect.isSelected(); // Deaktiviert wegen PraesentationErstellenMenuItem
  }
}
