package de.ivu.elect.presentation.wahlvorschlag;

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

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

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.GruppeConstants;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahlvorschlag.boundary.WahlvorschlagCommonEdit;
import de.ivu.elect.business.wahlvorschlag.boundary.WahlvorschlagConversationSelect;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
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.LambdaEntitySelectOneMenuProperty;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;
import org.apache.commons.lang3.StringUtils;


import static java.util.Objects.isNull;

@RequestScoped
@OnlineHilfeId("806")
@Named(WahlvorschlagGruppeWechselnView.COMPONENT_NAME)
@View(viewId = WahlvorschlagGruppeWechselnView.VIEW_ID, useCase = UseCasePermission.WAHLVORSCHLAG_GRUPPE_WECHSELN)
public class WahlvorschlagGruppeWechselnView extends AbstractElectEditView<Wahlvorschlag> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "wahlvorschlagGruppeWechselnView";

  public static final String VIEW_ID = "/wahlvorschlag/wahlvorschlag-gruppe-wechseln.xhtml";

  public static final String PARENT_VIEW_ID = WahlvorschlagSearchView.VIEW_ID;

  @Inject
  private transient WahlvorschlagConversationSelect wahlvorschlagConversationSelect;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  @Inject
  private transient WahlvorschlagCommonEdit wahlvorschlagCommonEdit;

  @Inject
  private transient WahlvorschlagGruppeFinder wahlvorschlagGruppeFinder;

  private PolitischeGruppe neueGruppe;

  @Nullable
  @PreConditionCheck
  public String checkPreCondition() {
    if (isNull(getEntity())) {
      return getStartViewId();
    }
    return null;
  }

  @Override
  protected Wahlvorschlag getEntity() {
    return wahlvorschlagConversationSelect.getEntity();
  }

  @Override
  protected void addProperties(FormBuilder formBuilder, Wahlvorschlag entity) {

    if (getNeueGruppe() == null) {
      setNeueGruppe(entity.getGruppe());
    }

    List<PolitischeGruppe> moeglicheGruppen = new ArrayList<>(wahlvorschlagGruppeFinder.findSupportedPolitischeGruppen(entity.getGebiet(), entity));
    moeglicheGruppen.add(0, entity.getGruppe());

    formBuilder.addProperty(
        new LambdaEntitySelectOneMenuProperty<>(moeglicheGruppen, this::setNeueGruppe, this::getNeueGruppe,
            this::getGruppeName,
            GruppeConstants.MESSAGE_KEY_ENTITY_EINZAHL, true, false));
  }

  protected PolitischeGruppe getNeueGruppe() {
    return neueGruppe;
  }

  protected void setNeueGruppe(PolitischeGruppe neueGruppe) {
    this.neueGruppe = neueGruppe;
  }

  protected String getGruppeName(Gruppe gruppe) {
    if (gruppe == null) {
      return "";
    }

    return String.format("%s (%s)", gruppe.getName(), gruppe.getSchluessel());
  }

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

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

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

  @Override
  @Redirect
  public String save() {
    Wahlvorschlag wahlvorschlag = getEntity();

    // ELECT-11012 beteiligte Namen vor dem Umhängen merken
    String wahlvorschlagKennwortAlt = wahlvorschlag.getKennwort();
    String wahlvorschlagKurznameAlt = wahlvorschlag.getKurzname();
    String wahlvorschlagZusatzbezeichnungAlt = wahlvorschlag.getZusatzbezeichnung();

    String gruppeNameNameAlt = getGruppeName(wahlvorschlag.getGruppe());
    String gruppeNameNameNeu = getGruppeName(getNeueGruppe());

    wahlvorschlagCommonEdit.gruppeWechseln(wahlvorschlag, getNeueGruppe());

    String wahlvorschlagKennwortNeu = wahlvorschlag.getKennwort();
    String wahlvorschlagKurznameNeu = wahlvorschlag.getKurzname();
    String wahlvorschlagZusatzbezeichnungNeu = wahlvorschlag.getZusatzbezeichnung();

    addInfoMessage("wahlvorschlag.gruppe.wechseln.erfolgreich", gruppeNameNameNeu, wahlvorschlagKennwortAlt, gruppeNameNameAlt);

    if (isGeaendert(wahlvorschlagKennwortAlt, wahlvorschlagKennwortNeu)) {
      addInfoMessage("wahlvorschlag.gruppe.wechseln.hinweis.kennwort.geaendert", wahlvorschlagKennwortAlt, wahlvorschlagKennwortNeu);
    }
    if (isGeaendert(wahlvorschlagKurznameAlt, wahlvorschlagKurznameNeu)) {
      addInfoMessage("wahlvorschlag.gruppe.wechseln.hinweis.kurzname.geaendert", nullToEmpty(wahlvorschlagKurznameAlt), nullToEmpty(wahlvorschlagKurznameNeu));
    }
    if (isGeaendert(wahlvorschlagZusatzbezeichnungAlt, wahlvorschlagZusatzbezeichnungNeu)) {
      addInfoMessage("wahlvorschlag.gruppe.wechseln.hinweis.zusatzbezeichnung.geaendert", nullToEmpty(wahlvorschlagZusatzbezeichnungAlt), nullToEmpty(wahlvorschlagZusatzbezeichnungNeu));
    }

    return goBack(PARENT_VIEW_ID);
  }

  private boolean isGeaendert(String alt, String neu) {
    if (StringUtils.isBlank(alt)) {
      return StringUtils.isNotBlank(neu);
    }
    return !alt.equals(neu);
  }

  private String nullToEmpty(String s) {
    if (s == null) {
      return "";
    }
    return s;
  }

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

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

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

  public String getWahlvorschlagName() {
    if (getEntity() == null) {
      return "";
    }
    return getEntity().getKennwort();
  }

  public Gebiet getGebiet() {
    if (getEntity() == null) {
      return null;
    }
    return getEntity().getGebiet();
  }

  public String getGebietName() {
    return gebietNummerFormatter.getDarstellung(getGebiet());
  }

  @Override
  protected void resetModel() {
    super.resetModel();
    setNeueGruppe(null);
  }

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