
package de.ivu.elect.presentation.gebietsbaum;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

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

import org.apache.deltaspike.core.api.scope.ConversationGroup;

import de.ivu.elect.business.gebietsbaum.boundary.AbstractGebietSearchParameters;
import de.ivu.elect.business.gebietsbaum.boundary.BaseGebietBoundaryCreate;
import de.ivu.elect.business.gebietsbaum.boundary.GebietSearchParameters;
import de.ivu.elect.business.gebietsbaum.boundary.GebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.boundary.GebietsartConversationSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.GebietConstants;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.security.UseCaseSecure;
import de.ivu.elect.jee.faces.AbstractEntityFacesValidator;
import de.ivu.elect.jee.faces.FacesContextUtil;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.GebietCreateViewInit;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.gebietsbaum.form.GebietUniqueUKFacesValidator;
import de.ivu.elect.presentation.gebietsbaum.form.GebietViewFormBuilder;
import de.ivu.elect.presentation.gebietsbaum.tree.AbstractNoStoreGebietsbaumView;
import de.ivu.elect.presentation.gebietsbaum.tree.GebietCreateViewPermissionCheck;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;

@RequestScoped
@OnlineHilfeId(value = "475", mehrfachVergebenOk = true)
@Named(AbstractGebietCreateNoScopeView.COMPONENT_NAME)
@View(viewId = AbstractGebietCreateNoScopeView.VIEW_ID, useCase = UseCasePermission.GEBIET_CREATE)
public class GebietCreateView extends AbstractGebietCreateView {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient GebietSessionSelect gebietSessionSelect;

  @Inject
  private transient GebietsartConversationSelect gebietsartConversationSelect;

  @Inject
  private transient GebietViewFormBuilder gebietViewFormBuilder;

  @Inject
  private transient AbstractNoStoreGebietsbaumView gebietsbaumView;

  @Inject
  @ConversationGroup(AbstractGebietSearchParameters.class)
  private transient GebietSearchParameters gebietSearchParameters;

  @Inject
  private transient GebietUniqueUKFacesValidator gebietUniqueUKFacesValidator;

  @Inject
  private transient BaseGebietBoundaryCreate create;

  @Inject
  private transient GebietCreateViewPermissionCheck gebietCreateViewPermissionCheck;

  @Inject
  private transient GebietCreateViewInit gebietCreateViewInit;

  public GebietCreateView() {
    super();
  }

  @Nullable
  @PreConditionCheck
  public String checkPreCondidtion() {
    if (gebietCreateViewPermissionCheck.isGebietCreatePossible()) {
      return null;
    }

    return getStartViewId();
  }

  @Override
  @PostConstruct
  public void init() {
    super.init();

    gebietCreateViewInit.init(getEntity());
  }

  @Override
  public void addProperties(FormBuilder formBuilder, Gebiet gebiet) {
    gebietViewFormBuilder.addGebietProperties(formBuilder, gebiet);
  }

  // KEIN @Redirect weil sonst die Eingabewerte beim Speichern verloren gehen, wenn der Unique-Validator anschlägt...
  @Override
  @UseCaseSecure(UseCasePermission.GEBIET_CREATE)
  public String save() {
    Gebiet entity = getEntity();

    gebietCreateViewInit.preSaveGebiet(entity);

    if (gebietUniqueUKFacesValidator.isValid(entity)) {
      FacesContextUtil.redirectToView(super.save());

      return null;
    }

    addErrorMessage(AbstractEntityFacesValidator.DETAIL_KEY, "", entity.getGebietsart().getTitelWennLeerName() + ", " + entity.getNummer());

    return getViewId();
  }

  @Override
  protected void callSave(Gebiet entity) {
    create.saveFromView(entity);

    // Gebiet bei Erfassungsgebieten nicht setzen, um schneller weitere Gebiete erfassen zu können
    if (entity.getGebietsart().getBezirksart().isKeine()) {
      gebietsbaumView.reset();
      gebietSessionSelect.setEntity(entity);
      gebietSearchParameters.setUebergeordnetesGebiet(gebietSessionSelect.getEntity());
    }
  }

  @Override
  @Nullable
  @Redirect
  public String goBack() {
    gebietsartConversationSelect.clearEntity();

    return super.goBack();
  }

  @Override
  protected FormBuilder createFormBuilder() {
    return new FormBuilder(formBuilderConfig);
  }

  public String getPageTitle() {
    return getMessage("entity.create.page.title", getGebietsartName());
  }

  public String getPageHeader() {
    return getMessage("entity.create.page.header", getGebietsartName());
  }

  private String getGebietsartName() {
    if (getEntity() != null && getEntity().getGebietsart() != null && isNotBlank(getEntity().getGebietsart().getTitel())) {
      return getEntity().getGebietsart().getTitel();
    }

    return getMessage(GebietConstants.MESSAGE_KEY_ENTITY_EINZAHL);
  }
}
