
package de.ivu.elect.presentation.menu;

import static java.util.stream.Collectors.toSet;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.boundary.SecurityGebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelector;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.jee.faces.FacesContextUtil;
import de.ivu.elect.jee.faces.FacesMessageUtil;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;
import de.ivu.elect.presentation.gebietsbaum.tree.AbstractNoStoreGebietsbaumView;
import de.ivu.elect.presentation.security.EinsehenGebietSecurity;

public class MainMenuSearchGebietLoader implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient GebietExtendedDAO gebietDao;

  @Inject
  private transient WahlSessionSelector wahlSelect;

  @Inject
  private transient SecurityGebietSessionSelect securityGebietSelect;

  @Inject
  private transient EinsehenGebietSecurity einsehenGebietSecurity;

  @Inject
  private transient AbstractNoStoreGebietsbaumView gebietsbaumView;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  public MainMenuSearchGebietLoader() {
    super();
  }

  public Set<String> erzeugeGebietsnamen() {
    return findGebiete().stream() //
        .filter(einsehenGebietSecurity::isRechtVorhanden).map(gebiet -> formatNameMitNummer(gebiet)) //
        .collect(toSet());
  }

  public void select(String gebietName) {
    Gebiet gebiet = findGebiet(gebietName);

    if (gebiet == null) {
      return;
    }

    if (securityGebietSelect.isSetzenErlaubt(gebiet)) {
      gebietsbaumView.reset();
      securityGebietSelect.setEntity(gebiet);

      FacesMessageUtil.addInfoMessage("gebiet.selected", "gebiet.selected", formatNameMitNummer(gebiet));
      FacesContextUtil.redirectToView(FacesContextUtil.getCurrentViewId());
    }
  }

  private Gebiet findGebiet(String gebietName) {
    for (Gebiet gebiet : findGebiete()) {
      if (gebietName.equalsIgnoreCase(formatNameMitNummer(gebiet))) {
        return gebiet;
      }
    }

    return null;
  }

  protected List<Gebiet> findGebiete() {
    if (wahlSelect.isSelected()) {
      return findGebiete(wahlSelect.getEntity());
    }

    return Collections.emptyList();
  }

  protected List<Gebiet> findGebiete(Wahl wahl) {
    return gebietDao.findByWahl(wahl);
  }

  protected List<Gebiet> findGebiete(Wahltermin wahltermin) {
    return gebietDao.findByWahltermin(wahltermin);
  }

  private String formatNameMitNummer(Gebiet gebiet) {
    return gebietNummerFormatter.getNameMitNummer(gebiet);
  }
}
