
package de.ivu.elect.presentation;

import static java.util.Objects.isNull;
import static org.apache.commons.lang3.StringUtils.defaultString;

import javax.annotation.Nullable;
import javax.inject.Inject;

import de.ivu.elect.business.benutzerverwaltung.entity.Benutzer;
import de.ivu.elect.business.benutzerverwaltung.entity.BenutzerEinsatzort;
import de.ivu.elect.business.gebietsbaum.boundary.GebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.security.control.ElectCommonPrincipal;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelector;
import de.ivu.elect.business.wahl.boundary.WahlterminSessionSelect;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.jee.entity.Entity;
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.redirect.Redirect;
import de.ivu.elect.jee.presentation.security.StartViewResolver;
import de.ivu.elect.jee.presentation.view.AbstractView;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;
import de.ivu.elect.presentation.mandant.MandantSessionSelect;
import de.ivu.elect.presentation.security.BearbeitenGebietSecurity;
import de.ivu.elect.presentation.security.EinsehenGebietSecurity;
import de.ivu.elect.presentation.security.GebietSecurity;
import de.ivu.elect.presentation.security.SperrmerkmalSecurity;
import de.ivu.elect.presentation.table.AbstractColumnEntry;

public abstract class AbstractElectCreateView<T extends Entity< ? , ? >> extends AbstractView implements DynamicFormEditOrCreateView {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient ElectCommonPrincipal principal;

  @Inject
  private transient GebietSecurity gebietSecurity;

  @Inject
  private transient SperrmerkmalSecurity sperrmerkmalSecurity;

  @Inject
  private transient StartViewResolver startViewResolver;

  @Inject
  private transient WahlterminSessionSelect wahlterminSessionSelect;

  @Inject
  private transient WahlSessionSelector wahlSessionSelector;

  @Inject
  private transient GebietSessionSelect gebietSessionSelect;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  @Inject
  private transient MandantSessionSelect mandantSessionSelect;

  private AdvancedDynaFormModel model;

  private String sperrmerkmalStyleClass;

  public AbstractElectCreateView() {
    super();
  }

  protected Benutzer getSelectedBenutzer() {
    return getPrincipal().getLogin();
  }

  protected String getSelectedBenutzerKennung() {
    return getPrincipal().getBenutzerKennung();
  }

  protected BenutzerEinsatzort getSelectedBenutzerEinsatzort() {
    return getPrincipal().getBenutzerEinsatzort();
  }

  protected String getSelectedBenutzerNameFormatted() {
    return getPrincipal().getFormattedName();
  }

  protected boolean hasPermission(UseCasePermission permission) {
    return getPrincipal().hasUseCasePermission(permission);
  }

  protected ElectCommonPrincipal getPrincipal() {
    return principal;
  }

  protected BearbeitenGebietSecurity getBearbeitenGebietSecurity() {
    return gebietSecurity.getBearbeitenGebietSecurity();
  }

  protected EinsehenGebietSecurity getEinsehenGebietSecurity() {
    return gebietSecurity.getEinsehenGebietSecurity();
  }

  protected String getStartViewId() {
    return startViewResolver.getStartViewId();
  }

  protected boolean isWahlterminSelected() {
    return wahlterminSessionSelect.isSelected();
  }

  protected Wahltermin getSelectedWahltermin() {
    return wahlterminSessionSelect.getEntity();
  }

  protected boolean isWahlSelected() {
    return wahlSessionSelector.isSelected();
  }

  protected Wahl getSelectedWahl() {
    return wahlSessionSelector.getEntity();
  }

  protected boolean isGebietSelected() {
    return gebietSessionSelect.isSelected();
  }

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

  protected String getSelectedGebietNameFormatted() {
    return formatGebietName(getSelectedGebiet());
  }

  protected String formatGebietName(Gebiet gebiet) {
    return gebietNummerFormatter.getDarstellung(gebiet);
  }

  protected abstract T getEntity();

  @Override
  public AdvancedDynaFormModel getModel() {
    if (isNull(model)) {
      model = createModel();
    }

    return model;
  }

  protected AdvancedDynaFormModel createModel() {
    FormBuilder formBuilder = createFormBuilder();

    addProperties(formBuilder, getEntity());

    return formBuilder.createModel();
  }

  protected abstract void addProperties(FormBuilder formBuilder, T entity);

  protected void resetModel() {
    model = null;
  }

  @Override
  public abstract boolean isBtnSaveRendered();

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

  @Override
  @Redirect
  public abstract String save();

  @Override
  @Nullable
  @Redirect
  public abstract String reset();

  @Override
  public abstract boolean isBtnResetRendered();

  @Override
  @Redirect
  public abstract String cancel();

  @Override
  public abstract boolean isBtnCancelRendered();

  @Override
  public String getStyleClass() {
    String result = super.getStyleClass();

    // ELECT-7171
    if (sperrmerkmalSecurity.isSperreVorhandenUndHervorzuheben(getEntity())) {
      result += " " + getSperrmerkmalStyleClass();
    }

    return result;
  }

  private String getSperrmerkmalStyleClass() {
    if (sperrmerkmalStyleClass == null) {
      sperrmerkmalStyleClass = defaultString(getMessage(AbstractColumnEntry.MSG_KEY_SPERRMERKMAL_STYLE_CLASS), "");
    }

    return sperrmerkmalStyleClass;
  }

  @Override
  public boolean isBtnShowAllFormFieldsRendered() {
    return super.isBtnShowAllFormFieldsRendered() || getModel().isAnyPropertyHiddenOnPageLoad();
  }

  protected Mandant getMandant() {
    return mandantSessionSelect.getMandant();
  }
}
