package de.ivu.elect.presentation.praesentation;

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

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

import org.apache.deltaspike.core.api.scope.ConversationGroup;

import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.mandant.boundary.MandantExtendedDAO;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.praesentation.boundary.PraesentationStatistikSearch;
import de.ivu.elect.business.praesentation.boundary.PraesentationStatistikSearchParameters;
import de.ivu.elect.business.praesentation.entity.PraesentationStatistikSearchResult;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.boundary.WahlartExtendedDAO;
import de.ivu.elect.business.wahl.entity.Wahlart;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaDateProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaStringSelectOneProperty;
import de.ivu.elect.presentation.AbstractElectSearchView;
import de.ivu.elect.presentation.LambdaEntitySelectOneMenuProperty;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.security.AbstractGebietSecurityFilter;


import static java.util.Arrays.asList;

@RequestScoped
@Named(PraesentationStatistikSearchView.COMPONENT_NAME)
@View(viewId = PraesentationStatistikSearchView.VIEW_ID, useCase = UseCasePermission.PRAESENTATION_STATISTIK_SEARCH)
public class PraesentationStatistikSearchView extends AbstractElectSearchView<PraesentationStatistikSearchResult> {

  public static final String VIEW_ID = "/praesentation/praesentation-statistik-search.xhtml";

  public static final String COMPONENT_NAME = "praesentationStatistikSearchView";

  private static final long serialVersionUID = 1L;

  @Inject
  private transient MandantExtendedDAO mandantExtendedDAO;

  @Inject
  private transient PraesentationStatistikSearch search;

  @Inject
  private transient WahlartExtendedDAO wahlartExtendedDAO;

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

  @Override
  protected List<PraesentationStatistikSearchResult> performSearch() {
    return search.getSearchResult(getSearchParameters());
  }

  @Override
  protected AbstractGebietSecurityFilter<PraesentationStatistikSearchResult> getGebietSecurityFilter() {
    return KEIN_GEBIET_SECURITY_FILTER;
  }

  @Override
  protected void presetSearchParameters() {

  }

  @Override
  public void addProperties(FormBuilder formBuilder) {
    if (isNurSystemMandant()) {
      List<Mandant> alleMandanten = mandantExtendedDAO.findByAll().stream().filter(m -> m.getArt().isCustomerMandant()).collect(Collectors.toList());
      formBuilder.addProperty(new LambdaEntitySelectOneMenuProperty<>(alleMandanten, this::setSearchMandant, this::getSearchMandant,
          m -> m.getNummer() + " - " + m.getName(), "praesentation.statistik.search.mandant", false, true));
    }
    formBuilder.addProperty(new LambdaDateProperty(getMessage("praesentation.statistik.search.wahldatum"), false, getSearchParameters()::setWahldatum,
        getSearchParameters()::getWahldatum));
    formBuilder.addProperty(new LambdaStringSelectOneProperty(getMessage("praesentation.statistik.search.wahlart"), false, getSearchParameters()::setWahlart,
        getSearchParameters()::getWahlart,
        findeWahlarten(), true));
    formBuilder.addProperty(new LambdaEnumProperty<>(getMessage("praesentation.statistik.search.ergebnisart"), false, getSearchParameters()::setErgebnisart,
        getSearchParameters()::getErgebnisart,
        Ergebnisart.class, asList(Ergebnisart.VORLAEUFIG, Ergebnisart.ENDGUELTIG), true));
  }

  protected void setSearchMandant(Mandant mandant) {
    if (mandant == null) {
      getSearchParameters().setMandantPK(null);
    } else {
      getSearchParameters().setMandantPK(mandant.getPk());
    }
  }

  @Nullable
  protected Mandant getSearchMandant() {
    if (getSearchParameters().getMandantPK() == null) {
      return null;
    }
    return mandantExtendedDAO.findByPrimaryKey(getSearchParameters().getMandantPK());
  }

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

  @Override
  public PraesentationStatistikSearchParameters getSearchParameters() {
    if (!isNurSystemMandant()) {
      searchParameters.setMandantPK(getMandant().getPk());
    }
    return searchParameters;
  }

  private boolean isNurSystemMandant() {
    return getMandant().getMandant().getArt().isSystemMandant() && !getMandant().getMandant().getArt().isCustomerMandant();
  }

  protected List<String> findeWahlarten() {
    if (isNurSystemMandant()) {
      return mandantExtendedDAO.findByAll().stream()
          .flatMap(mandant -> wahlartExtendedDAO.findByAllOrderByName(mandant).stream().map(Wahlart::getName).collect(Collectors.toSet()).stream())
          .distinct().sorted().collect(Collectors.toList());
    }
    return wahlartExtendedDAO.findByAllOrderByName(getMandant()).stream().map(Wahlart::getName).distinct().collect(Collectors.toList());
  }

}

