
package de.ivu.elect.dokumente.stimmeingabe;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.SortedMap;

import de.ivu.document.generator.template.annotations.DocumentMethod;
import de.ivu.document.generator.template.annotations.DocumentParam;
import de.ivu.document.generator.template.annotations.DocumentSimpleField;
import de.ivu.elect.business.ergebnis.control.ErgebnisDatenQuorum;
import de.ivu.elect.dokumente.DokumentFormatter;
import de.ivu.elect.dokumente.DokumentFormatterSettings;

// Cf. ReferendumOptionMitStimmergebnissenDocument!!!
public class ReferendumOptionStimmenDocument extends AbstractStimmenDocument {

  private static final long serialVersionUID = 1L;

  @DocumentSimpleField("Quorum/Prozenthuerde")
  public BigDecimal quorum; // ELECT-13212

  @DocumentSimpleField("Quorum/Prozenthuerde-Formatiert")
  public String quorumFormatiert; // ELECT-13212

  @DocumentSimpleField("ReferendumOption-Label")
  public String referendumOptionLabel;

  @DocumentSimpleField("ReferendumOption-Kurzbezeichnung")
  public String referendumOptionKurzbezeichnung;

  @DocumentSimpleField("Anzahl-Stimmen-Gueltig")
  public Long anzahlStimmen;

  @DocumentSimpleField("Anzahl-Stimmen-Gueltig-Formatiert")
  public String anzahlStimmenFormatiert;

  @DocumentSimpleField("Anteil-Stimmen-Gueltig")
  public BigDecimal anteilStimmen; // ELECT-13212

  @DocumentSimpleField("Anteil-Stimmen-Gueltig-Formatiert")
  public String anteilStimmenFormatiert; // ELECT-13212

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

  @DocumentMethod // ELECT-13212
  public boolean isQuorumErreicht(@DocumentParam("Grundwert") Long grundwert) {
    return anzahlStimmen != null && anzahlStimmen > 0L && anzahlStimmen >= berechneAnzahlStimmenQuorumErreicht(grundwert);
  }

  @DocumentMethod // ELECT-13212
  public long berechneAnzahlStimmenQuorumErreicht(@DocumentParam("Grundwert") Long grundwert) {
    return ErgebnisDatenQuorum.calculateAnzahlQuorumErreicht(quorum, grundwert);
  }

  public void addToDocumentKumuliert(StimmeingabeDocumentContext context, CoreStimmeingabeDocumentBuilder stimmeingabeDocumentBuilder,
      ReferendumOptionStimmenDocument referendumOptionStimmenDocument) {
    super.addToDocumentKumuliert(context, stimmeingabeDocumentBuilder, referendumOptionStimmenDocument);

    Locale locale = context.getLocale();

    referendumOptionStimmenDocument.quorum = quorum;
    referendumOptionStimmenDocument.quorumFormatiert = DokumentFormatter.formatProzent(referendumOptionStimmenDocument.quorum, locale);

    referendumOptionStimmenDocument.referendumOptionLabel = referendumOptionLabel;
    referendumOptionStimmenDocument.referendumOptionKurzbezeichnung = referendumOptionKurzbezeichnung;

    referendumOptionStimmenDocument.anzahlStimmen = aggregate(referendumOptionStimmenDocument.anzahlStimmen, anzahlStimmen);
    referendumOptionStimmenDocument.anzahlStimmenFormatiert = DokumentFormatter.formatNumber(referendumOptionStimmenDocument.anzahlStimmen, locale);

    referendumOptionStimmenDocument.anteilStimmen = aggregate(referendumOptionStimmenDocument.anteilStimmen, anteilStimmen);
    referendumOptionStimmenDocument.anteilStimmenFormatiert = DokumentFormatter.formatBigDecimal(referendumOptionStimmenDocument.anteilStimmen, DokumentFormatterSettings.PROZENTWERT_ANZAHL_NACHKOMMASTELLEN_DEFAULT, locale);
  }

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

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

      if (tk != null) {
        targetPerKey.putIfAbsent(tk, stimmeingabeDocumentBuilder.createReferendumOptionStimmenDocument(context));
        source.addToDocumentKumuliert(context, stimmeingabeDocumentBuilder, targetPerKey.get(tk));
      }
    }

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