
package de.ivu.elect.dokumente.wahlausschuss;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import de.ivu.document.generator.template.annotations.Document;
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.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.wahlausschuss.entity.WahlausschussEntschaedigung;
import de.ivu.elect.business.wahlausschuss.entity.Wahlausschussmitglied;
import de.ivu.elect.dokumente.CoreElectContext;
import de.ivu.elect.dokumente.ElectDocument;
import de.ivu.elect.dokumente.gebiet.GebietMitHierarchieDokument;

@Document(DokumentVorlageArt.WAHLAUSSCHUSSMITGLIEDER_ALS_LISTE_DOKUMENT_PREFIX)
public class WahlausschussmitgliederAlsListeDocument extends ElectDocument {

  private static final long serialVersionUID = 1L;

  @DocumentComplexField("Gebiet")
  public final GebietMitHierarchieDokument gebiet;

  @DocumentRepeat(value = "Wahlausschussmitglieder", elementClass = WahlausschussmitgliedDokument.class, itemName = "wahlausschussmitglied")
  public final List<WahlausschussmitgliedDokument> wahlausschussmitglieder;

  @DocumentSimpleField("Summe-Entschaedigungen")
  public final BigDecimal summeEntschaedigungen;

  @DocumentSimpleField("Summe-Entschaedigungen-Formatiert")
  public final String summeEntschaedigungenFormatted;

  @DocumentSimpleField("Summe-Entschaedigungen-Formatiert-Mit-Waehrung")
  public final String summeEntschaedigungenMitWaehrung;

  @DocumentSimpleField("Summe-Entschaedigungen-Formatiert-Mit-Waehrungszeichen")
  public final String summeEntschaedigungenMitWaehrungszeichen;

  @DocumentSimpleField("Summe-Entschaedigungen-Waehrung")
  public final String summeEntschaedigungenWaehrung;

  @DocumentSimpleField("Summe-Entschaedigungen-Waehrungszeichen")
  public final String summeEntschaedigungenWaehrungszeichen;

  public WahlausschussmitgliederAlsListeDocument(CoreElectContext coreElectContext, List<Wahlausschussmitglied> wahlausschussmitglieder, Gebiet gebiet) {
    super(coreElectContext);

    this.gebiet = new GebietMitHierarchieDokument(coreElectContext, gebiet);

    this.wahlausschussmitglieder = erstelleWahlausschussmitglieder(coreElectContext, wahlausschussmitglieder);

    String waehrungAlsIsoCode = anyWahlausschussEntschaedigung(coreElectContext, wahlausschussmitglieder).map(WahlausschussEntschaedigung::getWaehrungAlsIsoCode).orElse("");

    this.summeEntschaedigungen = summiereEntschaedingungenDerWahlausschussmitglieder(coreElectContext, wahlausschussmitglieder);
    this.summeEntschaedigungenFormatted = coreElectContext.formatBetrag(this.summeEntschaedigungen);
    this.summeEntschaedigungenMitWaehrung = coreElectContext.formatBetragMitWaehrungskuerzel(this.summeEntschaedigungen, waehrungAlsIsoCode);
    this.summeEntschaedigungenMitWaehrungszeichen = coreElectContext.formatBetragMitWaehrungssymbol(this.summeEntschaedigungen, waehrungAlsIsoCode);

    this.summeEntschaedigungenWaehrung = coreElectContext.formatWaehrungskuerzel(waehrungAlsIsoCode);
    this.summeEntschaedigungenWaehrungszeichen = coreElectContext.formatWaehrungssymbol(waehrungAlsIsoCode);
  }

  private Optional<WahlausschussEntschaedigung> anyWahlausschussEntschaedigung(CoreElectContext coreElectContext, List<Wahlausschussmitglied> wahlausschussmitglieder) {
    return wahlausschussmitglieder.stream() //
        .map(wahlausschussmitglied -> wahlausschussmitglied.getWahlausschussEntschaedigung(coreElectContext.getWahlausschussEntschaedigungDAO())) //
        .filter(Optional::isPresent).map(Optional::get) //
        .findAny();
  }

  private BigDecimal summiereEntschaedingungenDerWahlausschussmitglieder(CoreElectContext coreElectContext, List<Wahlausschussmitglied> wahlausschussmitglieder) {
    BigDecimal summe = BigDecimal.ZERO;

    for (Wahlausschussmitglied wahlausschussmitglied : wahlausschussmitglieder) {
      summe = summe.add(wahlausschussmitglied.getWahlausschussEntschaedigung(coreElectContext.getWahlausschussEntschaedigungDAO()).map(WahlausschussEntschaedigung::getBetrag).orElse(BigDecimal.ZERO));
    }

    return summe;
  }

  private List<WahlausschussmitgliedDokument> erstelleWahlausschussmitglieder(CoreElectContext coreElectContext, List<Wahlausschussmitglied> wahlausschussmitglieder) {
    List<WahlausschussmitgliedDokument> result = new ArrayList<>();

    Long laufendeNummer = 1L;

    for (Wahlausschussmitglied wahlausschussmitglied : wahlausschussmitglieder) {
      result.add(new WahlausschussmitgliedDokument(coreElectContext, wahlausschussmitglied, laufendeNummer++));
    }

    return result;
  }
}
