
package de.ivu.elect.presentation.ergebnis.dokumente.gesamtergebnis;

import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.STIMMEINGABE_WAHLART_ERGEBNISART_VORLAEUFIG_ERFASSUNGSART;

import java.util.List;
import java.util.Optional;

import de.ivu.document.generator.template.annotations.DocumentComplexField;
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.ErgebnisDaten;
import de.ivu.elect.business.ergebnis.entity.Stimmabgabeart;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.GebietPK;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisartVorlaeufigErfassungsart;
import de.ivu.elect.dokumente.ElectDocument;
import de.ivu.elect.dokumente.WasElectContext;
import de.ivu.elect.dokumente.gebiet.BasicGebietDokument;
import de.ivu.elect.dokumente.wahl.UmgangWaehlerDocument;
import de.ivu.elect.dokumente.wahl.UmgangWahlberechtigteDocument;

public class BaseErgebnisDokument extends ElectDocument {

  private static final long serialVersionUID = 1L;

  private final Stimmabgabeart stimmabgabeart;

  @DocumentComplexField("Wahlart-Umgang-Wahlberechtigte") // ELECT-13015
  public final UmgangWahlberechtigteDocument wahlartUmgangWahlberechtigte;

  @DocumentComplexField("Wahlart-Umgang-Waehler") // ELECT-13015
  public final UmgangWaehlerDocument wahlartUmgangWaehler;

  @DocumentSimpleField("IsErgebnisVorlaeufig")
  public final boolean isErgebnisVorlaeufig;

  @DocumentSimpleField("IsErgebnisEndgueltig")
  public final boolean isErgebnisEndgueltig;

  @DocumentSimpleField("IsErgebnis-Nur-Trendmeldung")
  public final boolean isErgebnisNurTrendmeldung; // ELECT-14019

  @DocumentSimpleField("Vorläufig/Endgültig")
  public final String vorlaeufigOderEndgueltig;

  @DocumentSimpleField("vorläufig/endgültig")
  public final String vorlaeufigOderEndgueltigLowercase;

  @DocumentSimpleField("CustomData-ErgebnisDaten")
  public final Object customDataErgebnisDaten;

  private final WasElectContext wasElectContext;

  public BaseErgebnisDokument(WasElectContext wasElectContext, ErgebnisDaten ergebnisDaten) {
    this(wasElectContext, ergebnisDaten, ergebnisDaten.getGebiete(), Stimmabgabeart.GESAMT);
  }

  public BaseErgebnisDokument(WasElectContext wasElectContext, ErgebnisDaten ergebnisDaten, List<Wahldurchfuehrungsgebiet> auswertungsgebiete, Stimmabgabeart stimmabgabeart) {
    super(wasElectContext);

    this.wasElectContext = wasElectContext;

    WahlartErgebnisart wahlartErgebnisart = ergebnisDaten.getErgebnis().getErgebnisart();

    this.wahlartUmgangWahlberechtigte = wahlartErgebnisart.isEndgueltig() ? this.wahlartUmgangWahlberechtigteEndgueltig : this.wahlartUmgangWahlberechtigteVorlaeufig;
    this.wahlartUmgangWaehler = wahlartErgebnisart.isEndgueltig() ? this.wahlartUmgangWaehlerEndgueltig : this.wahlartUmgangWaehlerVorlaeufig;

    this.stimmabgabeart = stimmabgabeart;

    // ELECT-14019
    Optional<WahlartErgebnisartVorlaeufigErfassungsart> ergebnisVorlaeufigErfassungsartIfConfigured = Optional.ofNullable(
        wasElectContext.getWahlParameterLoader().resolveEnumValue(ergebnisDaten.getWahl(), STIMMEINGABE_WAHLART_ERGEBNISART_VORLAEUFIG_ERFASSUNGSART, WahlartErgebnisartVorlaeufigErfassungsart.class));

    this.isErgebnisVorlaeufig = wahlartErgebnisart.isVorlaeufig();
    this.isErgebnisEndgueltig = wahlartErgebnisart.isEndgueltig();
    this.isErgebnisNurTrendmeldung = ergebnisVorlaeufigErfassungsartIfConfigured.map(WahlartErgebnisartVorlaeufigErfassungsart::isTrendmeldung).orElse(false);

    this.vorlaeufigOderEndgueltig = wahlartErgebnisart.isVorlaeufig() ? "Vorläufig" : "Endgültig";
    this.vorlaeufigOderEndgueltigLowercase = wahlartErgebnisart.isVorlaeufig() ? "vorläufig" : "endgültig";

    this.customDataErgebnisDaten = wasElectContext.getErgebnisDatenCustomDataDocumentBuilder().createCustomData(wasElectContext, ergebnisDaten, auswertungsgebiete, stimmabgabeart);
  }

  protected Stimmabgabeart getStimmabgabeart() {
    return stimmabgabeart;
  }

  @DocumentMethod // ELECT-13860
  public boolean isSitzverteilungPerMehrheitswahl(@DocumentParam("gebiet") Object gebietReference) {
    Long gebietId = null;

    if (gebietReference instanceof Gebiet) {
      gebietId = ((Gebiet) gebietReference).getId();
    } else if (gebietReference instanceof GebietPK) {
      gebietId = ((GebietPK) gebietReference).getId();
    } else if (gebietReference instanceof BasicGebietDokument) {
      gebietId = ((BasicGebietDokument) gebietReference).id;
    }

    return gebietId != null && wasElectContext.isSitzverteilungPerMehrheitswahl(new GebietPK(gebietId));
  }
}
