
package de.ivu.elect.dokumente.entschaedigung;

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

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.entschaedigung.entity.AuszahlungCalculated;
import de.ivu.elect.business.entschaedigung.entity.Entschaedigung;
import de.ivu.elect.dokumente.BaseElectContext;
import de.ivu.elect.dokumente.ElectDocument;

@Document(DokumentVorlageArt.AUSZAHLUNG_DOCUMENT_PREFIX)
public class AuszahlungDocument extends ElectDocument {

  private static final long serialVersionUID = 1L;

  @DocumentComplexField("Auszahlungsinformationen")
  public final AuszahlungBaseDocument auszahlungsinformationen;

  @DocumentRepeat(value = "Entschaedigungen", elementClass = EntschaedigungDocument.class, itemName = "entschaedigung")
  public final List<EntschaedigungDocument> entschaedigungen;

  @DocumentSimpleField(value = "Entschaedigungen-Anzahl")
  public final Integer entschaedigungenAnzahl;

  @DocumentSimpleField("Entschaedigungen-Gesamtbetrag")
  public final BigDecimal entschaedigungenGesamtbetrag;

  @DocumentSimpleField("Entschaedigungen-Gesamtbetrag-Formatiert")
  public final String entschaedigungenGesamtbetragFormatted;

  @DocumentSimpleField("Entschaedigungen-Gesamtbetrag-Formatiert-Mit-Waehrung")
  public final String entschaedigungenGesamtbetragMitWaehrung;

  @DocumentSimpleField("Entschaedigungen-Gesamtbetrag-Formatiert-Mit-Waehrungszeichen")
  public final String entschaedigungenGesamtbetragMitMitWaehrungszeichen;

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

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

  @DocumentRepeat(value = "EntschaedigungenPerZahlungsempfaengerMitGesamtbetrag", elementClass = EntschaedigungGruppierungMitGesamtbetragDocument.class, itemName = "entschaedigungGruppierungMitGesamtbetrag")
  public final List<EntschaedigungGruppierungMitGesamtbetragDocument> entschaedigungenPerZahlungsempfaengerMitGesamtbetrag;

  public AuszahlungDocument(BaseElectContext baseElectContext, AuszahlungCalculated auszahlungCalculated) {
    super(baseElectContext);

    this.auszahlungsinformationen = new AuszahlungBaseDocument(baseElectContext, auszahlungCalculated.getAuszahlung());

    this.entschaedigungen = createEntschaedigungDocuments(baseElectContext, auszahlungCalculated);
    this.entschaedigungenAnzahl = this.entschaedigungen.size();

    if (auszahlungCalculated.hasEntschaedigungen()) {
      String waehrungAlsIsoCode = auszahlungCalculated.getEntschaedigungenWaehrungAlsIsoCode();

      this.entschaedigungenGesamtbetrag = auszahlungCalculated.calculateEntschaedigungenGesamtbetrag();
      this.entschaedigungenGesamtbetragFormatted = baseElectContext.formatBetrag(this.entschaedigungenGesamtbetrag);
      this.entschaedigungenGesamtbetragMitWaehrung = baseElectContext.formatBetragMitWaehrungskuerzel(this.entschaedigungenGesamtbetrag, waehrungAlsIsoCode);
      this.entschaedigungenGesamtbetragMitMitWaehrungszeichen = baseElectContext.formatBetragMitWaehrungssymbol(this.entschaedigungenGesamtbetrag, waehrungAlsIsoCode);

      this.entschaedigungenWaehrung = baseElectContext.formatWaehrungskuerzel(waehrungAlsIsoCode);
      this.entschaedigungenWaehrungszeichen = baseElectContext.formatWaehrungssymbol(waehrungAlsIsoCode);
    } else {
      this.entschaedigungenGesamtbetrag = BigDecimal.ZERO;
      this.entschaedigungenGesamtbetragFormatted = "";
      this.entschaedigungenGesamtbetragMitWaehrung = "";
      this.entschaedigungenGesamtbetragMitMitWaehrungszeichen = "";

      this.entschaedigungenWaehrung = "";
      this.entschaedigungenWaehrungszeichen = "";
    }

    this.entschaedigungenPerZahlungsempfaengerMitGesamtbetrag = createEntschaedigungenPerZahlungsempfaengerMitGesamtbetragDocuments(baseElectContext, auszahlungCalculated);
  }

  private static List<EntschaedigungDocument> createEntschaedigungDocuments(BaseElectContext baseElectContext, AuszahlungCalculated auszahlungCalculated) {
    List<EntschaedigungDocument> result = new ArrayList<>();

    List<Entschaedigung> entschaedigungenCalculated = auszahlungCalculated.getEntschaedigungen();

    for (int i = 0; i < entschaedigungenCalculated.size(); i++) {
      result.add(new EntschaedigungDocument(baseElectContext, i + 1, entschaedigungenCalculated.get(i)));
    }

    return result;
  }

  private static List<EntschaedigungGruppierungMitGesamtbetragDocument> createEntschaedigungenPerZahlungsempfaengerMitGesamtbetragDocuments(BaseElectContext baseElectContext,
      AuszahlungCalculated auszahlungCalculated) {
    List<EntschaedigungGruppierungMitGesamtbetragDocument> result = new ArrayList<>();

    String beschreibungMsgKeyPrefix = "Entschaedigungsart.";
    String entschaedigungenWaehrungAlsIsoCode = auszahlungCalculated.getEntschaedigungenWaehrungAlsIsoCode();

    List<Entry<String, Entschaedigung>> gesamtentschaedigungPerPersonendatenArt = new ArrayList<>(auszahlungCalculated.getGesamtentschaedigungPerPersonendatenArt().entrySet());
    gesamtentschaedigungPerPersonendatenArt.sort((one, another) -> one.getKey().compareTo(another.getKey()));

    for (int i = 0; i < gesamtentschaedigungPerPersonendatenArt.size(); i++) {
      Entry<String, Entschaedigung> entry = gesamtentschaedigungPerPersonendatenArt.get(i);

      Entschaedigung entschaedigung = entry.getValue();
      String beschreibung = baseElectContext.getMessage(beschreibungMsgKeyPrefix + entry.getKey());

      result.add(new EntschaedigungGruppierungMitGesamtbetragDocument(baseElectContext, i + 1, beschreibung, entschaedigung.getGesamtbetrag(), entschaedigungenWaehrungAlsIsoCode));
    }

    return result;
  }
}
