package de.ivu.elect.presentation.ergebnis.dokumente.gesamtergebnis;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;

import de.ivu.elect.was.exchange.diff.EmlErgebnisDifferenz;

public class NlGesamtErgebnisDokumentDiffFilter implements Serializable {

  private static final long serialVersionUID = 1L;

  public GesamtErgebnisDokument filter(GesamtErgebnisDokument dokument, EmlErgebnisDifferenz emlErgebnisDifferenz) {

    for (var gebietMitListenDocument : dokument.gebieteMitListen) {
      if (emlErgebnisDifferenz != null) {

        Set<ListeMitStimmergebnissenDocument> listeMitStimmergebnissenDocumentToRemove = new HashSet<>();

        for (var listenMitStimmergebnis : gebietMitListenDocument.listenMitStimmergebnis) {

          if (isListeVeraendert(listenMitStimmergebnis, emlErgebnisDifferenz)) {

            Set<KandidaturMitStimmergebnissenDocument> kandidaturMitStimmergebnissenDocumentToRemove = new HashSet<>();

            for (KandidaturMitStimmergebnissenDocument kandidaturMitStimmergebnissenDocument : listenMitStimmergebnis.listenkandidaturen) {

              if (isListenkandidaturVeraendert(listenMitStimmergebnis, kandidaturMitStimmergebnissenDocument, emlErgebnisDifferenz)) {
                //
              } else {
                kandidaturMitStimmergebnissenDocumentToRemove.add(kandidaturMitStimmergebnissenDocument);
              }

            }

            listenMitStimmergebnis.listenkandidaturen.removeAll(kandidaturMitStimmergebnissenDocumentToRemove);
            listenMitStimmergebnis.listenkandidaturenSortiertNachRang.removeAll(kandidaturMitStimmergebnissenDocumentToRemove);
            listenMitStimmergebnis.listenkandidaturenGewaehlt.removeAll(kandidaturMitStimmergebnissenDocumentToRemove);

          } else {
            listeMitStimmergebnissenDocumentToRemove.add(listenMitStimmergebnis);
          }

        }

        gebietMitListenDocument.listenMitStimmergebnis.removeAll(listeMitStimmergebnissenDocumentToRemove);

      }

      return dokument; // nur ein Gebiet betrachten

    }

    return dokument;
  }

  private boolean isListenkandidaturVeraendert(ListeMitStimmergebnissenDocument listenMitStimmergebnis, KandidaturMitStimmergebnissenDocument kandidaturMitStimmergebnissenDocument, EmlErgebnisDifferenz emlErgebnisDifferenz) {

    return emlErgebnisDifferenz.getKandidatenStimmenUnterschied()
        .getOrDefault(getListenSchluessel(listenMitStimmergebnis), Collections.emptyMap())
        .get(getKandidatenSchluessel(kandidaturMitStimmergebnissenDocument)) != null;

  }

  private String getKandidatenSchluessel(KandidaturMitStimmergebnissenDocument kandidaturMitStimmergebnissenDocument) {
    return toStringNotNull(kandidaturMitStimmergebnissenDocument.listenkandidaturPositionStimmzettel);
  }

  private boolean isListeVeraendert(ListeMitStimmergebnissenDocument listenMitStimmergebnis, EmlErgebnisDifferenz emlErgebnisDifferenz) {
    return emlErgebnisDifferenz.getListenMitUnterschieden().contains(getListenSchluessel(listenMitStimmergebnis));
  }

  @Nonnull
  private String getListenSchluessel(ListeMitStimmergebnissenDocument listenMitStimmergebnis) {
    return toStringNotNull(listenMitStimmergebnis.ordnungszahl);
  }

  private String toStringNotNull(Long aLong) {
    if (aLong == null) {
      return "";
    }
    return aLong.toString();
  }

  private EmlErgebnisDifferenz bestimmeEmlDifferenz(GebietMitListenDocument gebietMitListenDocument, Map<String, EmlErgebnisDifferenz> emlErgebnisDifferenNachGebiet) {
    return emlErgebnisDifferenNachGebiet.get(gebietMitListenDocument.nummer);
  }

}
