
package de.ivu.elect.presentation.wahl;

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

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Nullable;
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.konfiguration.entity.CustomParameterKategorie;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.boundary.AbstractWahlParameterSearchParameters;
import de.ivu.elect.business.wahl.boundary.WahlParameterEdit;
import de.ivu.elect.business.wahl.boundary.WahlParameterSearch;
import de.ivu.elect.business.wahl.boundary.WahlParameterSearchParameters;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlParameter;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.jee.entity.EagerLoadingCollector;
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.AbstractElectEditView;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;
import de.ivu.elect.presentation.konfiguration.form.CustomParameterViewFormBuilder;

@RequestScoped
@OnlineHilfeId("786")
@Named(WahlDokumentplatzhalterEditView.COMPONENT_NAME)
@View(viewId = WahlDokumentplatzhalterEditView.VIEW_ID, useCase = UseCasePermission.WAHL_DOKUMENT_PLATZHALTER_PARAMETER_EDIT)
public class WahlDokumentplatzhalterEditView extends AbstractElectEditView<WahlParameter> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "wahlDokumentplatzhalterEditView";

  public static final String VIEW_ID = "/wahl/wahl-dokumentplatzhalter-edit.xhtml";

  public static final String TRENNZEICHEN = " - ";

  @Inject
  private transient WahlParameterSearch wahlParameterSearch;

  @Inject
  private transient WahlParameterEdit wahlParameterEdit;

  @Inject
  @ConversationGroup(AbstractWahlParameterSearchParameters.class)
  private transient WahlParameterSearchParameters wahlParameterSearchParameters;

  @Inject
  private transient CustomParameterViewFormBuilder customParameterViewFormBuilder;

  protected List<WahlParameter> wahlParameterListe;

  public WahlDokumentplatzhalterEditView() {
    super();
  }

  @Nullable
  @PreConditionCheck
  public String checkCondition() {
    if (!isWahlSelected() && !isWahlterminSelected()) {
      return getStartViewId();
    }

    return null;
  }

  @Override
  protected boolean isGebietBearbeitenRechtPruefen() {
    return false;
  }

  @Override
  protected WahlParameter getEntity() {
    return new WahlParameter();
  }

  protected List<WahlParameter> getWahlParameterListe() {
    if (wahlParameterListe == null) {
      Wahltermin wahltermin = getSelectedWahltermin();
      Wahl wahl = getSelectedWahl();

      wahlParameterSearchParameters.setWahlterminWahlGesetzt(true);
      wahlParameterSearchParameters.setWahl(wahl);
      wahlParameterSearchParameters.setWahltermin(wahltermin);

      wahlParameterSearchParameters.setKategorie(CustomParameterKategorie.DOKUMENTPLATZHALTER);
      wahlParameterSearchParameters.setLimit(null);

      wahlParameterListe = wahlParameterSearch.getSearchResult(wahlParameterSearchParameters, EagerLoadingCollector.create());
      wahlParameterSearchParameters.reset();
    }

    return wahlParameterListe;
  }

  @Override
  protected void addProperties(FormBuilder formBuilder, WahlParameter ignored) {
    String keinSeparatorPrefix = "<IGNORED>-";

    List<WahlParameter> wahlParameterSorted = getWahlParameterListe();
    Map<String, List<WahlParameter>> wahlParameterSortedPerSeparator = new LinkedHashMap<>(); // Reihenfolge beibehalten, aber gleiche Gruppen (gleicher Separator) zusammenfassen...

    for (int i = 0; i < wahlParameterSorted.size(); i++) {
      WahlParameter wahlParameter = wahlParameterSorted.get(i);

      String kurzname = wahlParameter.getKurzname(getMessages());
      String separator = keinSeparatorPrefix + i;

      if (kurzname.contains(TRENNZEICHEN)) {
        separator = kurzname.substring(0, kurzname.indexOf(TRENNZEICHEN));
      }

      wahlParameterSortedPerSeparator.computeIfAbsent(separator, key -> new ArrayList<>()).add(wahlParameter);
    }

    for (Entry<String, List<WahlParameter>> entry : wahlParameterSortedPerSeparator.entrySet()) {
      String separator = entry.getKey();

      if (!startsWith(separator, keinSeparatorPrefix)) {
        formBuilder.addSeparator("wahl.dokumentvorlagen.platzhalter.edit.separator", separator);
      }

      for (WahlParameter wahlParameter : entry.getValue()) {
        String kurzname = wahlParameter.getKurzname(getMessages());
        String label = kurzname;

        if (kurzname.contains(TRENNZEICHEN)) {
          label = kurzname.substring(kurzname.indexOf(TRENNZEICHEN) + TRENNZEICHEN.length());
        }

        customParameterViewFormBuilder.addProperty(formBuilder, wahlParameter, wahlParameter.getProperties().getWertProperty(), UseCasePermission.WAHL_PARAMETER_EDIT_SECRETS_CLEAR_TEXT, label,
            wahlParameter.getBeschreibung(getMessages()));
      }
    }
  }

  @Override
  protected boolean isSavePermissionVorhanden() {
    return hasPermission(UseCasePermission.WAHL_DOKUMENT_PLATZHALTER_PARAMETER_EDIT);
  }

  @Override
  @Redirect
  public String save() {
    wahlParameterEdit.save(getWahlParameterListe());

    wahlParameterListe = null;

    addMessageSaveSuccess();

    return getStartViewId();
  }

  protected void addMessageSaveSuccess() {
    addInfoMessage("wahl.dokumentvorlagen.platzhalter.edit.action.save.success.message");
  }

  @Override
  public String delete() {
    throw new UnsupportedOperationException();
  }

  @Nullable
  @Override
  @Redirect
  public String reset() {
    super.reset();

    return VIEW_ID;
  }

  @Override
  protected void resetModel() {
    super.resetModel();

    wahlParameterListe = null;
  }

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

  @Override
  @Redirect
  public String cancel() {
    wahlParameterListe = null;

    return getStartViewId();
  }
}
