
package de.ivu.elect.presentation.stimmeingabe.exchange;

import static java.util.Arrays.asList;

import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;

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

import de.ivu.elect.business.exchange.entity.DateienImportierenVerzeichnisStatus;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeImportStatusSearch;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeImportStatusSearchParameters;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeImportStatus;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.presentation.charts.PieChartModelBuilder;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaStringProperty;
import de.ivu.elect.jee.presentation.dynamicform.ReadOnlyStringProperty;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.jee.presentation.search.AbstractSearchParameters;
import de.ivu.elect.presentation.AbstractElectSearchView;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;
import de.ivu.elect.presentation.security.AbstractGebietSecurityFilter;

@ViewAccessScoped
@OnlineHilfeId("705")
@Named(StimmeingabeImportStatusSearchView.COMPONENT_NAME)
@View(viewId = StimmeingabeImportStatusSearchView.VIEW_ID, useCase = UseCasePermission.STIMMEINGABE_IMPORT_STATUS_SEARCH)
public class StimmeingabeImportStatusSearchView extends AbstractElectSearchView<StimmeingabeImportStatus> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "stimmeingabeImportStatusSearchView";

  public static final String VIEW_ID = "/stimmeingabe/stimmeingabe-import-status-search.xhtml";

  @Inject
  private transient StimmeingabeImportStatusSearch search;

  @Inject
  @ConversationGroup(StimmeingabeImportStatusSearchParameters.class)
  private transient StimmeingabeImportStatusSearchParameters searchParameters;

  private PieChartModel statusPieChartModel;

  public StimmeingabeImportStatusSearchView() {
    super();
  }

  @PreConditionCheck
  public String checkCondition() {
    if (!isWahlSelected()) {
      addErrorMessage("wahl.selected.missing");

      return getStartViewId();
    }

    return null;
  }

  @Override
  public void searchPartialUpdate() {
    statusPieChartModel = null;

    super.searchPartialUpdate();
  }

  public PieChartModel getStatusPieChartModel() {
    if (statusPieChartModel == null) {
      PieChartModelBuilder modelBuilder = PieChartModelBuilder.getDefaultInstance();

      fillStatusPieChartModel(modelBuilder);

      statusPieChartModel = modelBuilder.buildModel();
    }

    return statusPieChartModel;
  }

  public boolean isShowStatus() {
    return isSearchReady() && !getStatusPieChartModel().getData().isEmpty();
  }

  private void fillStatusPieChartModel(PieChartModelBuilder modelBuilder) {
    if (getSearchParameters().isFindAll()) {
      Map<DateienImportierenVerzeichnisStatus, Long> counted = getSearchResult().stream().collect(Collectors.groupingBy(StimmeingabeImportStatus::getVerzeichnisArt, Collectors.counting()));

      for (DateienImportierenVerzeichnisStatus verzeichnisStatus : DateienImportierenVerzeichnisStatus.values()) {
        Long anzahl = counted.getOrDefault(verzeichnisStatus, 0L);

        modelBuilder.add(getMessage(verzeichnisStatus) + " - " + format(anzahl), anzahl, verzeichnisStatus.getFarbe());
      }
    }
  }

  protected String format(Long anzahl) {
    return NumberFormat.getIntegerInstance(getUserLocale().getLocale()).format(anzahl);
  }

  @Override
  protected List<StimmeingabeImportStatus> performSearch() {
    statusPieChartModel = null;

    return search.getSearchResult(getSearchParameters());
  }

  @Override
  protected AbstractGebietSecurityFilter<StimmeingabeImportStatus> getGebietSecurityFilter() {
    return AbstractGebietSecurityFilter.createKeinFilter();
  }

  @Override
  public void addProperties(FormBuilder formBuilder) {
    if (getSearchParameters().getDateinamen().isEmpty()) {
      String wildcardTooltip = getMessage(AbstractSearchParameters.WILDCARD_TOOLTIP_MSG_KEY);

      formBuilder
          .addProperty(new LambdaStringProperty(getMessage("stimmeingabe.import.status.header.dateiname"), false, getSearchParameters()::setDateiname, getSearchParameters()::getDateiname, 0, 1000))
          .withTooltip(wildcardTooltip);
    } else {
      formBuilder.addProperty(new ReadOnlyStringProperty(getMessage("stimmeingabe.import.status.header.dateinamen"), String.join(", ", getSearchParameters().getDateinamen())));
    }

    formBuilder.addProperty(new LambdaEnumProperty<>(getMessage("stimmeingabe.import.status.header.verzeichnisArt"), false, getSearchParameters()::setVerzeichnisArt,
        getSearchParameters()::getVerzeichnisArt, DateienImportierenVerzeichnisStatus.class, asList(DateienImportierenVerzeichnisStatus.values()), true));
  }

  @Override
  protected String getViewId() {
    return VIEW_ID;
  }

  @Override
  public StimmeingabeImportStatusSearchParameters getSearchParameters() {
    searchParameters.setWahl(getSelectedWahl());
    return searchParameters;
  }

  @Override
  public void presetSearchParameters() {
    getSearchParameters().setWahl(getSelectedWahl());
  }

  @Override
  public String reset() {
    statusPieChartModel = null;

    return super.reset();
  }

  @Override
  public boolean isBtnGoBackRendered() {
    return viewStackContainsOtherViewsAndShouldNotReset();
  }

  @Nullable
  @Override
  @Redirect
  public String goBack() {
    getSearchParameters().reset(); // Für Import der nächsten Datei zurücksetzen

    return super.goBack();
  }
}
