package de.ivu.elect.presentation.wahllokalsystem;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

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

import org.apache.deltaspike.core.api.scope.ViewAccessScoped;
import org.primefaces.model.chart.PieChartModel;

import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlPK;
import de.ivu.elect.business.wahllokalsystem.boundary.WahllokalsystemStatusStatusuebersicht;
import de.ivu.elect.business.wahllokalsystem.entity.WahllokalsystemStatus;
import de.ivu.elect.business.wahllokalsystem.entity.WahllokalsystemStatusDokumentEventType;
import de.ivu.elect.business.wahllokalsystem.entity.WahllokalsystemStatusOnline;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.presentation.charts.PieChartModelBuilder;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.AbstractElectStatusuebersichtView;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;
import de.ivu.elect.presentation.wahllokalsystem.menu.WahllokalsystemStatusSearchMenuItemEntry;

@RequestScoped // ELECTMUC-2374
@Named(WahllokalsystemStatusStatusuebersichtView.COMPONENT_NAME)
@View(viewId = WahllokalsystemStatusStatusuebersichtView.VIEW_ID, useCase = UseCasePermission.WAHLLOKALSYSTEM_STATUS_SEARCH)
@OnlineHilfeId(value = "760")
public class WahllokalsystemStatusStatusuebersichtView extends AbstractElectStatusuebersichtView<WahllokalsystemStatus> {

  public static final String COMPONENT_NAME = "wahllokalsystemStatusStatusuebersichtView";

  public static final String VIEW_ID = "/wahllokalsystem/wahllokalsystem-status-statusuebersicht.xhtml";


  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahllokalsystemStatusStatusuebersicht wahllokalsystemStatusStatusuebersicht;

  @Inject
  private transient WahllokalsystemStatusSearchMenuItemEntry wahllokalsystemStatusSearchMenuItemEntry;

  private transient Map<WahlPK, PieChartModel> statusPieChartModelFuerWahl = new ConcurrentHashMap<>();

  private transient PieChartModel onlinePieChartModell;

  @PreConditionCheck
  public String checkCondition() {

    if (!isGebietSelected()) {
      return getStartViewId();
    }
    return null;
  }

  @Override
  protected void fillStatusPieChartModel(PieChartModelBuilder pieChartModelBuilder) {
    fillStatusPieChartModel(pieChartModelBuilder, null);
  }

  public PieChartModel getStatusPieChartModelFuerWahl(Wahl wahl) {
    return statusPieChartModelFuerWahl.computeIfAbsent(wahl.getPk(), x -> {
      PieChartModelBuilder modelBuilder = createPieChartModelBuilder();

      fillStatusPieChartModel(modelBuilder, wahl);

      return modelBuilder.buildModel();
    });
  }


  public PieChartModel getOnlinePieChartModel() {
    if (onlinePieChartModell==null){
      PieChartModelBuilder modelBuilder = createPieChartModelBuilder();

      fillOnlinePieChartModel(modelBuilder);

      onlinePieChartModell =  modelBuilder.buildModel();

    }
    return onlinePieChartModell;
  }


  private void fillStatusPieChartModel(PieChartModelBuilder pieChartModelBuilder, @Nullable Wahl andereWahl) {
    Map<WahllokalsystemStatusDokumentEventType, ? extends Number> map = wahllokalsystemStatusStatusuebersicht
        .getAnzahlWahllokalsystemStatusDokumentEventType(getSelectedGebiet(), andereWahl);

    for (Map.Entry<WahllokalsystemStatusDokumentEventType, ? extends Number> entry : map.entrySet()) {
      Number anzahl = entry.getValue();
      if (anzahl == null) {
        anzahl = 0L;
      }
      pieChartModelBuilder.add(getMessage(entry.getKey()) + " - " + format(anzahl), anzahl, entry.getKey().getColor());
    }
  }

  private void fillOnlinePieChartModel(PieChartModelBuilder pieChartModelBuilder) {
    Map<WahllokalsystemStatusOnline, ? extends Number> map = wahllokalsystemStatusStatusuebersicht.getOnlineStatus(getSelectedGebiet());
    for (Map.Entry<WahllokalsystemStatusOnline, ? extends Number> entry : map.entrySet()) {
      Number anzahl = entry.getValue();
      if (anzahl == null) {
        anzahl = 0L;
      }
      pieChartModelBuilder.add(getMessage(entry.getKey()) + " - " + format(anzahl), anzahl, entry.getKey().getColor());
    }
  }



  public String getNameAktuelleWahl() {
    return getNameDerWahl(getSelectedWahl());

  }

  public String getNameDerWahl(Wahl wahl) {
    return wahl.getWahlart().getWahlartName();
  }

  public List<Wahl> getWeitereWahlen() {
    Wahl selectedWahl = getSelectedWahl();

    if (selectedWahl == null) {
      return Collections.emptyList();
    }

    return selectedWahl.getWeitereWahlenAmWahltermin();
  }

  @Override
  protected void resetModel() {
    super.resetModel();
    statusPieChartModelFuerWahl.clear();
    onlinePieChartModell = null;
  }

  public boolean isBtnSearchRendered() {
    return wahllokalsystemStatusSearchMenuItemEntry.isRendered();
  }

  public String getBtnSearchLabel() {
    return wahllokalsystemStatusSearchMenuItemEntry.getLabelFinal();
  }

  @Redirect
  public String search() {
    return wahllokalsystemStatusSearchMenuItemEntry.getTargetViewId();
  }

}
