package de.ivu.elect.core.exchange.stimmen.csv.dynamic;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahlvorschlag.entity.Direktkandidat;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;


import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toMap;

public class StimmenDTOFactoryHelper {

  public void addHeaderDirektFuerWahlkreis(List<String> result, String headerPrefix, int anzahlZugelassenerGruppen) {
    for (int i = 1; i <= anzahlZugelassenerGruppen; i++) {
      result.add(headerPrefix + i);
    }

  }

  public void addHeaderDirektFuerWahlkreis(List<String> result, String headerPrefix, List<Long> stimmzettelPositionen) {
    for (Long aLong : stimmzettelPositionen) {
      result.add(prefixPosition(headerPrefix, aLong));
    }
  }

  protected String prefixPosition(String headerPrefix, Long aLong) {
    return headerPrefix + aLong;
  }

  public void addHeaderDirekt(List<String> result, String headerPrefix, Wahldurchfuehrungsgebiet wurzelgebiet, List<Direktkandidat> direktkandidats, EntityAufStimmzettelDaten entityAufStimmzettelDaten) {
    Long letztePosition = 0L;
    for (Direktkandidat direktkandidat : direktkandidats) {
      Long position = direktkandidat.getStimmzettelPosition(wurzelgebiet, entityAufStimmzettelDaten).getPosition();
      if (position == null) {
        position = ++letztePosition;
      } else {
        letztePosition = position;
      }
      result.add(prefixPosition(headerPrefix, position));
    }
  }

  public <E> LinkedHashMap<Long, E> sortMapByStimmZettelPosition(Map<Long, E> dinge) {
    return dinge.entrySet().stream().sorted(Map.Entry.comparingByKey())
        .collect(toMap(Map.Entry::getKey, Map.Entry::getValue,
            (oldValue, newValue) -> oldValue, LinkedHashMap::new));
  }

  public Long getStimmzettelPosition(Wahlvorschlag wahlvorschlag, EntityAufStimmzettelDaten entityAufStimmzettelDaten) {
    Long position = wahlvorschlag.getStimmzettelPosition(entityAufStimmzettelDaten).getPosition();
    return checkNull(position);
  }

  public Long checkNull(Long value) {
    return value != null ? value : Long.MAX_VALUE;
  }

  public <E extends Wahlvorschlag> Map<Long, List<E>> getNachStimmzettelpositionSortierteWahlvorschlaege(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet,
                                                                                                         List<E> wahlvorschlage, DynamicStimmenExchangeErgebnisDaten ergebnisDaten) {
    Map<Long, List<E>> zugelasseneDirektkandidatenZuGebietByStimmZettelPosition = wahlvorschlage.stream().
        filter(wahlvorschlag -> wahlvorschlag.isZugelassen() && wahlvorschlag.getGebiet()
            .isInGebietshierarchieVon(wahldurchfuehrungsgebiet) || wahlvorschlag.getGebiet().equals(wahldurchfuehrungsgebiet)).//ELECT-11783
            collect(groupingBy(wahlvorschlag -> getStimmzettelPosition(wahlvorschlag,
            ergebnisDaten.getEntityAufStimmzettelDaten())));
    return sortMapByStimmZettelPosition(zugelasseneDirektkandidatenZuGebietByStimmZettelPosition);
  }

}
