package de.ivu.elect.presentation.praesentation;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

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.internet.boundary.PraesentationUploadServiceKonfigurieren;
import de.ivu.elect.business.internet.control.PraesentationUploadService;
import de.ivu.elect.business.internet.control.PraesentationUploadServiceFinder;
import de.ivu.elect.business.internet.entity.PraesentationUploadServiceKonfiguration;
import de.ivu.elect.business.praesentation.entity.PraesentationUploadServiceStatus;
import de.ivu.elect.business.praesentation.entity.PraesentationUploadServiceTyp;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.entity.WahlParameterConstants;
import de.ivu.elect.business.wahl.entity.WahlParameterWerte;
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.LambdaPasswordProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaStringProperty;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.AbstractElectView;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;


import static java.util.Arrays.asList;

@RequestScoped
@Named(PraesentationUploadServiceKonfigurationView.COMPONENT_NAME)
@View(viewId = PraesentationUploadServiceKonfigurationView.VIEW_ID, useCase = UseCasePermission.PRAESENTATION_KONFIGURIEREN)
@OnlineHilfeId("775")
public class PraesentationUploadServiceKonfigurationView extends AbstractElectView implements DynamicFormEditOrCreateView {

  public static final String VIEW_ID = "/praesentation/praesentation-upload-service-konfiguration.xhtml";

  public static final String PARENT_VIEW_ID = PraesentationStatusView.VIEW_ID;

  public static final String COMPONENT_NAME = "praesentationUploadServiceKonfigurationView";

  private static final long serialVersionUID = 1L;

  private transient AdvancedDynaFormModel model = null;

  @Inject
  private transient PraesentationUploadServiceFinder praesentationUploadServiceFinder;

  @Inject
  private transient PraesentationUploadServiceKonfigurieren praesentationUploadServiceKonfigurieren;

  private PraesentationUploadServiceKonfiguration konfiguration = null;

  @Nullable
  @PreConditionCheck
  public String check() {
    if (!isWahlSelected()) {
      return getStartViewId();
    }

    return null;
  }

  @Override
  public AdvancedDynaFormModel getModel() {

    if (model == null) {
      FormBuilder formBuilder = new FormBuilder();
      formBuilder.withId("praesentationUpload");

      PraesentationUploadServiceKonfiguration konfiguration = getKonfiguration();

      formBuilder.addSeparator("praesentation.upload.service.konfiguration.allgemein");
      formBuilder.addProperty(
          new LambdaEnumProperty<>(messages.lokalisiere(WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_STATUS), true, konfiguration::setStatus,
              konfiguration::getStatus, PraesentationUploadServiceStatus.class, asList(PraesentationUploadServiceStatus.values()))).withKey("serviceStatus");
      List<PraesentationUploadServiceTyp> praesentationUploadServiceTypen = new ArrayList<>(praesentationUploadServiceFinder.getSupportedTypes());
        praesentationUploadServiceTypen.sort(Comparator.comparingInt(Enum::ordinal));

      formBuilder.addProperty(new LambdaEnumProperty<>(messages.lokalisiere(WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_TYP), true, konfiguration::setTyp,
          konfiguration::getTyp, PraesentationUploadServiceTyp.class, praesentationUploadServiceTypen)).withKey("serviceTyp");

      if (konfiguration.getTyp().isUrlEinblenden()) {
        formBuilder
          .addProperty(new LambdaStringProperty(messages.lokalisiere(WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_URL), false, konfiguration::setUrl,
            konfiguration::getUrl, 0, WahlParameterConstants.WERT_MAX_LENGTH)).withKey("serviceURL");
      }
      if (konfiguration.getTyp().isBenutzerkennungPasswortEinblenden()) {
        formBuilder.addProperty(
          new LambdaStringProperty(messages.lokalisiere(WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_BENUTZER), false, konfiguration::setBenutzer,
            konfiguration::getBenutzer, 0, WahlParameterConstants.WERT_MAX_LENGTH)).withKey("serviceBenutzer");
        formBuilder.addProperty(
          new LambdaPasswordProperty(messages.lokalisiere(WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_PASSWORT), false, konfiguration::setPasswort,
            konfiguration::getPasswort, 0, WahlParameterConstants.WERT_MAX_LENGTH, "", "")).withKey("servicePasswort");
        if (StringUtils.isBlank(konfiguration.getPasswort())) {
          formBuilder.withWarningMessage(messages.getMessageForMessageKey("praesentation.upload.service.passwort.fehlt"));
        } else {
          formBuilder.withLabel(messages.getMessageForMessageKey("praesentation.upload.service.neues.passwort"));
          formBuilder.withInfoMessage(messages.getMessageForMessageKey("praesentation.upload.service.passwort.gesetzt"));
        }
      }

      if (konfiguration.getTyp().isVorhanden()) {
        PraesentationUploadService praesentationUploadService = praesentationUploadServiceFinder.getPraesentationUploadService(konfiguration.getTyp());
        if (praesentationUploadService.isServicePropertiesPresent()) {
          formBuilder.addSeparator("praesentation.upload.service.konfiguration.speziell");
          praesentationUploadService.addServiceProperties(formBuilder, konfiguration.getInitialServiceParameter(), getMessages());
        }
      }

      model = formBuilder.createModel();
    }

    return model;

  }

  protected PraesentationUploadServiceKonfiguration getKonfiguration() {
    if (konfiguration == null) {
      konfiguration = praesentationUploadServiceKonfigurieren.getPraesentationUploadServiceKonfiguration(getSelectedWahl());
    }
    return konfiguration;
  }

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

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

  @Override
  @Redirect
  public String save() {

    if (konfiguration != null) {
      boolean spezialKonfigNotwendig;
      if (konfiguration.getInitialServiceParameter().getServiceTyp().equals(konfiguration.getTyp())) {
        spezialKonfigNotwendig = false;
        konfiguration.setKonfig(konfiguration.getInitialServiceParameter().getParsedKonfigJson());
      } else {
        spezialKonfigNotwendig = true;
      }

      if (spezialKonfigNotwendig){
        konfiguration.setUrl(messages.getMessageForMessageKey(konfiguration.getTyp().getDefaultUrlMessageKey()));
        if (!konfiguration.getTyp().isBenutzerkennungPasswortEinblenden()){
          konfiguration.setBenutzer("");
          konfiguration.resetPasswort();
        }
      }

      praesentationUploadServiceKonfigurieren.savePraesentationUploadServiceKonfiguration(getSelectedWahl(), konfiguration);

      if (spezialKonfigNotwendig) {
        addInfoMessage("praesentation.upload.service.konfiguration.save.type.changed");
        return reset();
      }
      addInfoMessage("praesentation.upload.service.konfiguration.save.success");
    }
    return goBack(PARENT_VIEW_ID);
  }

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

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

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

  @Override
  @Redirect
  public String cancel() {
    return goBack(PARENT_VIEW_ID);
  }
}
