
package de.ivu.elect.was.exchange.kerg;

import java.util.List;
import java.util.function.Function;

import javax.annotation.Nullable;

import de.ivu.elect.business.ergebnis.control.ErgebnisDaten;
import de.ivu.elect.business.ergebnis.entity.Stimmabgabeart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;

public class UebrigeKergGruppeContainer extends AbstractKergGruppeContainer<Gruppe> {

  private final boolean existUebrigeInGebietshierarchie;

  private final GueltigeKergGruppeContainer gueltigeKergGruppeContainer;

  private final List<PolitischeGruppeKergGruppeContainer> politischeGruppeKergGruppeContainers;

  public UebrigeKergGruppeContainer(ErgebnisDaten ergebnisDaten, Gruppe gruppe, Wahldurchfuehrungsgebiet gebiet, Stimmabgabeart stimmabgabeart, boolean existUebrigeInGebietshierarchie,
      GueltigeKergGruppeContainer gueltigeKergGruppeContainer, List<PolitischeGruppeKergGruppeContainer> politischeGruppeKergGruppeContainers) {
    super(ergebnisDaten, gruppe, gebiet, stimmabgabeart);

    this.existUebrigeInGebietshierarchie = existUebrigeInGebietshierarchie;

    this.gueltigeKergGruppeContainer = gueltigeKergGruppeContainer;

    this.politischeGruppeKergGruppeContainers = politischeGruppeKergGruppeContainers;
  }

  @Nullable
  @Override
  protected Long getErstStimmenAktuell() {
    if (existUebrigeInGebietshierarchie) {
      return bestimmeUebrige(AbstractKergGruppeContainer::getErstStimmenAktuell);
    }

    return null;
  }

  @Nullable
  @Override
  protected Long getErstStimmenVorperiode() {
    return bestimmeUebrige(AbstractKergGruppeContainer::getErstStimmenVorperiode);
  }

  @Nullable
  @Override
  protected Long getZweitStimmenAktuell() {
    // Da alle Gruppen der aktuellen Wahl (außer die Einzelbewerber) die Spalten in der KERG-Datei bilden, werden immer alle AKTUELLEN
    // Listenstimmen angezeigt und die "Übrigen" AKTUELLEN Listenstimmen sind (im Gegensatz zur Vorperiode) nie vorhanden.
    return null; // ELECT-12977 bestimmeUebrige(AbstractKergGruppeContainer::getZweitStimmenAktuell)
  }

  @Nullable
  @Override
  protected Long getZweitStimmenVorperiode() {
    return bestimmeUebrige(AbstractKergGruppeContainer::getZweitStimmenVorperiode);
  }

  private Long bestimmeUebrige(Function<AbstractKergGruppeContainer< ? extends Gruppe>, Long> anzahlStimmenFct) {
    Long anzahlGueltigeStimmen = anzahlStimmenFct.apply(gueltigeKergGruppeContainer);

    if (anzahlGueltigeStimmen == null) {
      return null;
    }

    Long summeGruppeStimmen = null;

    for (PolitischeGruppeKergGruppeContainer politischeGruppeKergGruppeContainer : politischeGruppeKergGruppeContainers) {
      Long anzahlGruppeStimmen = anzahlStimmenFct.apply(politischeGruppeKergGruppeContainer);

      if (anzahlGruppeStimmen != null) {
        summeGruppeStimmen = summeGruppeStimmen == null ? anzahlGruppeStimmen : summeGruppeStimmen + anzahlGruppeStimmen;
      }
    }

    if (summeGruppeStimmen != null) { // ELECTSL-113
      return Math.max(0L, anzahlGueltigeStimmen - summeGruppeStimmen);
    }

    return null;
  }
}
