
package de.ivu.elect.dokumente.stimmeingabe;

import static java.util.Objects.nonNull;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;

import de.ivu.document.generator.template.annotations.DocumentSimpleField;

public class GruppeStimmenDocument extends AbstractStimmenDocument {

  private static final long serialVersionUID = 1L;

  @DocumentSimpleField("Erststimmen-Erfassbar")
  public boolean erststimmenErfassbar;

  @DocumentSimpleField("Erststimmen-Gruppe-Bezeichnung")
  public String erststimmenGruppeBezeichnung;

  @DocumentSimpleField("Erststimmen-Kennung")
  public String erststimmenKennung;

  @DocumentSimpleField("Erststimmen-Bezeichnung")
  public String erststimmenBezeichnung;

  @DocumentSimpleField("Erststimmen-Gueltig")
  public Long anzahlErststimmen;

  @DocumentSimpleField("Zweitstimmen-Erfassbar")
  public boolean zweitstimmenErfassbar;

  @DocumentSimpleField("Zweitstimmen-Gruppe-Bezeichnung")
  public String zweitstimmenGruppeBezeichnung;

  @DocumentSimpleField("Zweitstimmen-Kennung")
  public String zweitstimmenKennung;

  @DocumentSimpleField("Zweitstimmen-Bezeichnung")
  public String zweitstimmenBezeichnung;

  @DocumentSimpleField("Zweitstimmen-Gueltig")
  public Long anzahlZweitstimmen;

  @DocumentSimpleField("Zweitstimmen-Gueltig-Nur-Liste")
  public Long anzahlZweitstimmenNurListe;

  @DocumentSimpleField("Zweitstimmen-Gueltig-Nur-Listenkandidaturen")
  public Long anzahlZweitstimmenNurListenkandidaturen;

  /**
   * @see StimmeingabeDocument#stimmzettelWahlvorschlagUnveraendert
   * @see ListeStimmenDocument#stimmzettelWahlvorschlagUnveraendert
   */
  @DocumentSimpleField("Stimmzettel-Nur-Einzelner-Wahlvorschlag-Unveraendert")
  public Long stimmzettelWahlvorschlagUnveraendert; // ELECT-13791

  /**
   * @see StimmeingabeDocument#stimmzettelWahlvorschlagVeraendert
   * @see ListeStimmenDocument#stimmzettelWahlvorschlagVeraendert
   */
  @DocumentSimpleField("Stimmzettel-Nur-Einzelner-Wahlvorschlag-Veraendert")
  public Long stimmzettelWahlvorschlagVeraendert; // ELECT-13791

  /**
   * @see StimmeingabeDocument#stimmzettelWahlvorschlagPanaschiert
   * @see ListeStimmenDocument#stimmzettelWahlvorschlagPanaschiert
   */
  @DocumentSimpleField("Stimmzettel-Nur-Einzelner-Wahlvorschlag-Panaschiert")
  public Long stimmzettelWahlvorschlagPanaschiert; // ELECT-13791

  /**
   * @see StimmeingabeDocument#stimmzettelWahlvorschlagGesamt
   * @see ListeStimmenDocument#stimmzettelWahlvorschlagGesamt
   */
  @DocumentSimpleField("Stimmzettel-Nur-Einzelner-Wahlvorschlag-Gesamt")
  public Long stimmzettelWahlvorschlagGesamt; // ELECT-13791

  public GruppeStimmenDocument(boolean eingabenAnzahlenStimmenExcluded) {
    super(eingabenAnzahlenStimmenExcluded);
  }

  public void addToDocumentKumuliert(StimmeingabeDocumentContext context, CoreStimmeingabeDocumentBuilder stimmeingabeDocumentBuilder, GruppeStimmenDocument gruppeStimmenDocument) {
    super.addToDocumentKumuliert(context, stimmeingabeDocumentBuilder, gruppeStimmenDocument);

    gruppeStimmenDocument.erststimmenErfassbar = erststimmenErfassbar;
    gruppeStimmenDocument.erststimmenGruppeBezeichnung = erststimmenGruppeBezeichnung;
    gruppeStimmenDocument.erststimmenKennung = erststimmenKennung;
    gruppeStimmenDocument.erststimmenBezeichnung = erststimmenBezeichnung;
    gruppeStimmenDocument.anzahlErststimmen = aggregate(gruppeStimmenDocument.anzahlErststimmen, anzahlErststimmen);

    gruppeStimmenDocument.zweitstimmenErfassbar = zweitstimmenErfassbar;
    gruppeStimmenDocument.zweitstimmenGruppeBezeichnung = zweitstimmenGruppeBezeichnung;
    gruppeStimmenDocument.zweitstimmenKennung = zweitstimmenKennung;
    gruppeStimmenDocument.zweitstimmenBezeichnung = zweitstimmenBezeichnung;
    gruppeStimmenDocument.anzahlZweitstimmen = aggregate(gruppeStimmenDocument.anzahlZweitstimmen, anzahlZweitstimmen);
    gruppeStimmenDocument.anzahlZweitstimmenNurListe = aggregate(gruppeStimmenDocument.anzahlZweitstimmenNurListe, anzahlZweitstimmenNurListe);
    gruppeStimmenDocument.anzahlZweitstimmenNurListenkandidaturen = aggregate(gruppeStimmenDocument.anzahlZweitstimmenNurListenkandidaturen, anzahlZweitstimmenNurListenkandidaturen);

    gruppeStimmenDocument.stimmzettelWahlvorschlagUnveraendert = aggregate(gruppeStimmenDocument.stimmzettelWahlvorschlagUnveraendert, stimmzettelWahlvorschlagUnveraendert);
    gruppeStimmenDocument.stimmzettelWahlvorschlagVeraendert = aggregate(gruppeStimmenDocument.stimmzettelWahlvorschlagVeraendert, stimmzettelWahlvorschlagVeraendert);
    gruppeStimmenDocument.stimmzettelWahlvorschlagPanaschiert = aggregate(gruppeStimmenDocument.stimmzettelWahlvorschlagPanaschiert, stimmzettelWahlvorschlagPanaschiert);
    gruppeStimmenDocument.stimmzettelWahlvorschlagGesamt = aggregate(gruppeStimmenDocument.stimmzettelWahlvorschlagGesamt, stimmzettelWahlvorschlagGesamt);
  }

  public static List<GruppeStimmenDocument> aggregate(StimmeingabeDocumentContext context, CoreStimmeingabeDocumentBuilder stimmeingabeDocumentBuilder, List<GruppeStimmenDocument> targets,
      List<GruppeStimmenDocument> sources) {
    SortedMap<Object, GruppeStimmenDocument> targetPerKey = collectStimmenDocumentToAggregatePerTk(targets);

    for (GruppeStimmenDocument source : sources) {
      Object tk = source.getTk();

      if (nonNull(tk)) {
        targetPerKey.putIfAbsent(tk, stimmeingabeDocumentBuilder.createGruppeStimmenDocument(context));
        source.addToDocumentKumuliert(context, stimmeingabeDocumentBuilder, targetPerKey.get(tk));
      }
    }

    return new ArrayList<>(targetPerKey.values());
  }
}
