package de.ivu.elect.wus.exchange.stimmzettel;

import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.stimmzettel.entity.StimmzettelDaten;
import de.ivu.elect.business.wahlvorschlag.entity.Direktkandidat;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.toList;

public class BtwStimmzettelWahlvorschlaegeBestimmer {

  private static final Logger LOG = LoggerFactory.getLogger(BtwStimmzettelWahlvorschlaegeBestimmer.class);

  public static List<BtwStimmzettelWahlvorschlaege> collectWahlvorschlaegeAufStimmzettelSorted(EntityAufStimmzettelDaten entityAufStimmzettelDaten, StimmzettelDaten stimmzettelDaten) {
    Map<Long, BtwStimmzettelWahlvorschlaege> wahlvorschlaegePerStimmzettelPosition = new HashMap<>();

    for (Liste liste : stimmzettelDaten.getListenAufgestellt()) {
      Long stimmzettelPosition = liste.getStimmzettelPosition(entityAufStimmzettelDaten).getPosition();

      if (stimmzettelPosition == null) { // ELECT-11415
        LOG.warn("Aufgestellte Liste OHNE gültige Stimmzettelposition IGNORIERT [liste = " + liste + "]");
      } else {
        wahlvorschlaegePerStimmzettelPosition.put(stimmzettelPosition, new BtwStimmzettelWahlvorschlaege(
            stimmzettelPosition, null, liste, stimmzettelDaten.getListenkandidaturen(liste)));
      }
    }

    for (Direktkandidat direktkandidat : stimmzettelDaten.getDirektkandidatenAufgestellt()) {
      Long stimmzettelPosition = direktkandidat.getStimmzettelPosition(entityAufStimmzettelDaten).getPosition();

      if (stimmzettelPosition == null) { // ELECT-11415
        LOG.warn("Aufgestellten Direktkandidaten OHNE gültige Stimmzettelposition IGNORIERT [direktkandidat = " + direktkandidat + "]");
      } else {
        wahlvorschlaegePerStimmzettelPosition.put(stimmzettelPosition,
            new BtwStimmzettelWahlvorschlaege(stimmzettelPosition, direktkandidat,
                wahlvorschlaegePerStimmzettelPosition.getOrDefault(stimmzettelPosition, BtwStimmzettelWahlvorschlaege.EMPTY).getListe(),
                wahlvorschlaegePerStimmzettelPosition.getOrDefault(stimmzettelPosition, BtwStimmzettelWahlvorschlaege.EMPTY).getListenkandidaturen()));
      }
    }

    return wahlvorschlaegePerStimmzettelPosition.values().stream() //
        .sorted(Comparator.comparing(BtwStimmzettelWahlvorschlaege::getStimmzettelPosition)) //
        .collect(toList());
  }
}
