
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.DocumentComplexField;
import de.ivu.document.generator.template.annotations.DocumentRepeat;
import de.ivu.document.generator.template.annotations.DocumentSimpleField;
import de.ivu.elect.dokumente.wahlvorschlag.GruppeDokument;

/**
 * NOTE, Frage steht in Gruppe#getName...
 */
// Cf. ReferendumVorlageMitStimmergebnissenDocument!!!
public class ReferendumVorlageStimmenDocument extends AbstractStimmenDocument {

  private static final long serialVersionUID = 1L;

  @DocumentSimpleField("Position-Fortlaufend")
  public Long positionFortlaufend;

  @DocumentComplexField("Gruppe")
  public GruppeDokument gruppeDokument;

  @DocumentSimpleField("Stimmen-Gueltig")
  public Long stimmenGueltig;

  @DocumentSimpleField("Kennung-Gueltig")
  public String kennungGueltig;

  @DocumentSimpleField("Bezeichnung-Gueltig")
  public String bezeichnungGueltig;

  @DocumentSimpleField("Stimmen-Ungueltig")
  public Long stimmenUngueltig;

  @DocumentSimpleField("Kennung-Ungueltig")
  public String kennungUngueltig;

  @DocumentSimpleField("Bezeichnung-Ungueltig")
  public String bezeichnungUngueltig;

  @DocumentSimpleField("Stimmen-Gesamt")
  public Long stimmen;

  @DocumentRepeat(value = "ReferendumOptionen", elementClass = ReferendumOptionStimmenDocument.class, itemName = "referendumOption")
  public List<ReferendumOptionStimmenDocument> referendumOptionen = new ArrayList<>();

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

  public void addToDocumentKumuliert(StimmeingabeDocumentContext context, CoreStimmeingabeDocumentBuilder stimmeingabeDocumentBuilder,
      ReferendumVorlageStimmenDocument referendumVorlageStimmenDocument) {
    super.addToDocumentKumuliert(context, stimmeingabeDocumentBuilder, referendumVorlageStimmenDocument);

    referendumVorlageStimmenDocument.positionFortlaufend = positionFortlaufend;

    referendumVorlageStimmenDocument.gruppeDokument = gruppeDokument;

    referendumVorlageStimmenDocument.kennungGueltig = kennungGueltig;
    referendumVorlageStimmenDocument.bezeichnungGueltig = bezeichnungGueltig;
    referendumVorlageStimmenDocument.stimmenGueltig = aggregate(referendumVorlageStimmenDocument.stimmenGueltig, stimmenGueltig);

    referendumVorlageStimmenDocument.kennungUngueltig = kennungUngueltig;
    referendumVorlageStimmenDocument.bezeichnungUngueltig = bezeichnungUngueltig;
    referendumVorlageStimmenDocument.stimmenUngueltig = aggregate(referendumVorlageStimmenDocument.stimmenUngueltig, stimmenUngueltig);

    referendumVorlageStimmenDocument.stimmen = aggregate(referendumVorlageStimmenDocument.stimmen, stimmen);

    referendumVorlageStimmenDocument.referendumOptionen = ReferendumOptionStimmenDocument.aggregate(context, stimmeingabeDocumentBuilder, referendumVorlageStimmenDocument.referendumOptionen,
        referendumOptionen);
  }

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

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

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

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