
package de.ivu.elect.presentation.dashboard.entries;

import java.util.List;
import java.util.stream.Collectors;

import javax.enterprise.inject.Specializes;
import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.control.GebietByBreadthFirstComparator;
import de.ivu.elect.business.gebietsbaum.entity.AbstractGebiet;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.ReadOnlyLongProperty;
import de.ivu.elect.jee.presentation.dynamicform.ReadOnlyStringProperty;
import de.ivu.elect.jee.presentation.status.OutputSeverity;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;
import de.ivu.elect.presentation.menu.AbstractMenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.WahlStatusuebersichtMenuItemEntry;

@Specializes
public class WasWahlDashboardEntry extends CoreWahlDashboardEntry {

  private static final long serialVersionUID = 1L;

  @Inject
  protected transient GebietExtendedDAO gebietExtendedDAO;

  @Inject
  protected transient GebietNummerFormatter gebietNummerFormatter;

  @Inject
  private transient WahlStatusuebersichtMenuItemEntry wahlStatusuebersichtMenuItemEntry;

  public WasWahlDashboardEntry() {
    super();
  }

  @Override
  public List<AbstractMenuItemEntry> getMenuItemsFirst() {
    List<AbstractMenuItemEntry> result = super.getMenuItemsFirst();
    result.add(wahlStatusuebersichtMenuItemEntry);

    return result;
  }

  @Override
  protected void addPropertiesFuerWahl(FormBuilder formBuilder, Wahl wahl) {
    super.addPropertiesFuerWahl(formBuilder, wahl);

    if (isWahlMitAnzahlSitze(wahl)) {
      List<Gebiet> wahlgebiete = getWahlgebiete(wahl);

      if (!wahlgebiete.isEmpty()) {
        formBuilder.addSeparator("was.wahl.dashboard.wahlgebiete.separator");

        for (Gebiet gebiet : wahlgebiete) {
          Long anzahlSitze = gebiet.getAnzahlSitze();

          if (anzahlSitze == null) {
            formBuilder.addProperty(new ReadOnlyStringProperty(gebietNummerFormatter.getDarstellung(gebiet), getMessage("component.value.null")));
          } else {
            formBuilder.addProperty(new ReadOnlyLongProperty(gebietNummerFormatter.getDarstellung(gebiet), anzahlSitze));
          }
        }
      }
    }
  }

  @Override
  protected OutputSeverity getSeverity() {
    Wahl wahl = wahlSessionSelector.getEntity();

    if (isWahlMitAnzahlSitze(wahl)) {
      List<Gebiet> wahlgebiete = getWahlgebiete(wahl);

      for (Gebiet gebiet : wahlgebiete) {
        // Cf. GebietViewFormBuilder#addGebietProperties!!!
        if (gebiet.getAnzahlSitze() == null && !gebiet.isDirektwahlgebiet()) {
          return OutputSeverity.WARN;
        }
      }
    }

    return super.getSeverity();
  }

  private List<Gebiet> getWahlgebiete(Wahl wahl) {
    return gebietExtendedDAO.findByWahl(wahl).stream().filter(AbstractGebiet::isWahlgebiet).sorted(GebietByBreadthFirstComparator.INSTANCE).collect(Collectors.toList());
  }

  private boolean isWahlMitAnzahlSitze(Wahl wahl) {
    return wahl != null && wahl.isWahlMitAnzahlSitze();
  }
}
