
package de.ivu.elect.presentation.gebietsbaum.menu;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.boundary.GebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.boundary.GebietsartConversationSelect;
import de.ivu.elect.business.gebietsbaum.boundary.GebietsartExtendedDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Gebietsart;
import de.ivu.elect.business.gebietsbaum.entity.GebietsartBezirksart;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelect;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.faces.FacesContextUtil;

public abstract class AbstractWasErfassungsgebietCreateMenuItemEntry extends AbstractGebietCreateMenuItemEntry {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient GebietsartExtendedDAO gebietsartExtendedDAO;

  @Inject
  private transient GebietsartConversationSelect gebietsartConversationSelect;

  @Inject
  private transient WahlSessionSelect wahlSelect;

  @Inject
  private transient ErfassungsgebietCreateMenuItemEnabled erfassungsgebietCreateMenuItemEnabled;

  @Inject
  private transient GebietSessionSelect gebietSessionSelect;

  public AbstractWasErfassungsgebietCreateMenuItemEntry() {
    super();
  }

  @Override
  public boolean isRendered() {
    return super.isRendered() && erfassungsgebietCreateMenuItemEnabled.isEnabled() && existsGebietsartByErfassungsgebietBezirksart();
  }

  @Override
  public String getTargetViewId() {
    return null; // and doAction...
  }

  @Override
  protected List<String> getAdditionalTopicViewIds() {
    return Collections.singletonList(super.getTargetViewId());
  }

  @Override
  public String doAction() {
    findGebietsartByErfassungsgebietBezirksart().ifPresent(gebietsartConversationSelect::setEntity);

    Gebiet selectedGebiet = getSelectedGebiet();

    if (selectedGebiet == null) {
      return FacesContextUtil.getCurrentViewId();
    }

    if (!selectedGebiet.getGebietsart().getBezirksart().isKeine()) {
      // Wir sind auf einem Bezirk => Anlegen auf nächsthöherer Ebene
      gebietSessionSelect.setEntity(selectedGebiet.getUebergeordnetesGebiet());
    }

    return super.getTargetViewId();
  }

  @Override
  protected boolean isIncludePageParameter() {
    return false; // Gebiet wird gewechselt
  }

  private boolean existsGebietsartByErfassungsgebietBezirksart() {
    return isWahlSelected() && findGebietsartByErfassungsgebietBezirksart().isPresent();
  }

  private Optional<Gebietsart> findGebietsartByErfassungsgebietBezirksart() {
    return gebietsartExtendedDAO.findByWahlart(getSelectedWahl().getWahlart()).stream() //
        .filter(gebietsart -> getErfassungsgebietGebietsartBezirksart().equals(gebietsart.getBezirksart())) //
        .findFirst();
  }

  @Override
  protected String getLabel() {
    return getMessage(getLabelKey(), getMessage(getErfassungsgebietGebietsartBezirksart()));
  }

  protected abstract GebietsartBezirksart getErfassungsgebietGebietsartBezirksart();

  @Override
  protected boolean isWahlOderWahlterminSelected() {
    return isWahlSelected();
  }

  private boolean isWahlSelected() {
    return wahlSelect.isSelected();
  }

  private Wahl getSelectedWahl() {
    return wahlSelect.getEntity();
  }

  @Override
  protected boolean isGebietCreatePossible() {
    return isWahlOderWahlterminSelected() && isGebietSelected() && (!isBezirkSelected() || isUebergeordnetesGebietVorhanden());
  }

  private boolean isUebergeordnetesGebietVorhanden() {
    return getSelectedGebiet() != null && getSelectedGebiet().hasUebergeordnetesGebiet();
  }
}
