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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import de.ivu.document.generator.template.BaseDocument;
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.ergebnis.control.ErgebnisDaten;
import de.ivu.elect.business.ergebniskonflikt.entity.ErgebnisKonflikt;
import de.ivu.elect.business.ergebniskonflikt.entity.ErgebnisKonfliktCustomData;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.Listenverbindung;
import de.ivu.elect.dokumente.CoreElectContext;
import de.ivu.elect.dokumente.gebiet.GebietDokument;

@Document(value = DokumentVorlageArt.LOS_SUB_TEMPLATE, isSubTemplate = true)
public class ErgebnisKonfliktDocument extends BaseDocument {

  private static final long serialVersionUID = 1L;

  @DocumentSimpleField("Art")
  public final String konfliktArt;

  @DocumentSimpleField("Status")
  public final String konfliktStatus;

  @DocumentSimpleField("IstGelöst")
  public final boolean geloest;

  @DocumentSimpleField("Beschreibung")
  public final String konfliktBeschreibung;

  @DocumentSimpleField("Lösung")
  public final String konfliktBeschreibungLoesung;

  @DocumentSimpleField("GelöstVon")
  public final String konfliktGeloestVon;

  @DocumentSimpleField("GelöstZeitpunkt")
  public final String konfliktGeloestZeitpunkt;

  @DocumentSimpleField("IstKandidaturenBeteiligt")
  public final boolean kandidaturenBeteiligt;

  @DocumentSimpleField("IstListenBeteiligt")
  public final boolean listenBeteiligt;

  @DocumentSimpleField("IstListenverbindungenBeteiligt")
  public final boolean listenverbindungenBeteiligt;

  @DocumentSimpleField("IstKandidaturenGelost")
  public final boolean kandidaturenGelost;

  @DocumentSimpleField("IstListengelost")
  public final boolean listenGelost;

  @DocumentSimpleField("IstListenverbindungenGelost")
  public final boolean listenverbindungenGelost;

  @DocumentRepeat(value = "BeteiligteKandidaturen", elementClass = KandidaturMitStimmergebnissenDocument.class, itemName = "kandidatur")
  public final List<KandidaturMitStimmergebnissenDocument> beteiligteKandidaturen;

  @DocumentRepeat(value = "GelosteKandidaturen", elementClass = KandidaturMitStimmergebnissenDocument.class, itemName = "kandidatur")
  public final List<KandidaturMitStimmergebnissenDocument> gelosteKandidaturen;

  @DocumentRepeat(value = "BeteiligteListen", elementClass = ListeMitStimmergebnissenDocument.class, itemName = "liste")
  public final List<ListeMitStimmergebnissenDocument> beteiligteListen;

  @DocumentRepeat(value = "GelosteListen", elementClass = ListeMitStimmergebnissenDocument.class, itemName = "liste")
  public final List<ListeMitStimmergebnissenDocument> gelosteListen;

  @DocumentRepeat(value = "BeteiligteListenverbindungen", elementClass = WasListenverbindungDokument.class, itemName = "listenverbindung")
  public final List<WasListenverbindungDokument> beteiligteListenverbindungen;

  @DocumentRepeat(value = "GelosteListenverbindungen", elementClass = WasListenverbindungDokument.class, itemName = "listenverbindung")
  public final List<WasListenverbindungDokument> gelosteListenverbindungen;

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

  public ErgebnisKonfliktDocument(CoreElectContext coreElectContext, ErgebnisDaten ergebnisDaten, ErgebnisKonflikt ergebnisKonflikt,
      Map<Liste, ListeMitStimmergebnissenDocument> ergebnisDokumentPerListe, Map<Listenverbindung, WasListenverbindungDokument> ergebnisDokumentPerListenverbindung,
      Map<Kandidatur, KandidaturMitStimmergebnissenDocument> ergebnisDokumentPerKandidatur) {
    super();

    this.konfliktArt = coreElectContext.getMessage(ergebnisKonflikt.getErgebnisKonfliktArt());
    this.konfliktStatus = coreElectContext.getMessage(ergebnisKonflikt.getErgebnisKonfliktStatus());
    this.geloest = ergebnisKonflikt.isGeloest();
    this.konfliktBeschreibung = ergebnisKonflikt.getKonfliktBeschreibung();
    this.konfliktBeschreibungLoesung = ergebnisKonflikt.getLoesungBeschreibung();
    this.konfliktGeloestVon = ergebnisKonflikt.getLoesungVon();
    this.konfliktGeloestZeitpunkt = coreElectContext.formatDateTimeMedium(ergebnisKonflikt.getLoesungZeitpunkt());

    ErgebnisKonfliktCustomData customData = ergebnisKonflikt.getCustomData(ErgebnisKonfliktCustomData.class);

    this.kandidaturenBeteiligt = customData.isKandidaturenBeteiligt();
    this.listenBeteiligt = customData.isListenBeteiligt();
    this.listenverbindungenBeteiligt = customData.isListenverbindungenBeteiligt();
    this.kandidaturenGelost = customData.isKandidaturenGelost();
    this.listenGelost = customData.isListenGelost();
    this.listenverbindungenGelost = customData.isListenverbindungenGelost();

    Collection<Kandidatur> kandidaturen = ergebnisDaten.getKandidaturen();

    this.beteiligteKandidaturen = new ArrayList<>();

    for (Kandidatur kandidatur : customData.getBeteiligteKandidaturen(kandidaturen)) {
      if (ergebnisDokumentPerKandidatur.containsKey(kandidatur)) {
        this.beteiligteKandidaturen.add(ergebnisDokumentPerKandidatur.get(kandidatur));
      }
    }

    this.gelosteKandidaturen = new ArrayList<>();

    for (Kandidatur kandidatur : customData.getGelosteKandidaturen(kandidaturen)) {
      if (ergebnisDokumentPerKandidatur.containsKey(kandidatur)) {
        this.gelosteKandidaturen.add(ergebnisDokumentPerKandidatur.get(kandidatur));
      }
    }

    Collection<Liste> listen = ergebnisDaten.getListen();

    this.beteiligteListen = new ArrayList<>();

    for (Liste liste : customData.getBeteiligteListen(listen)) {
      if (ergebnisDokumentPerListe.containsKey(liste)) {
        this.beteiligteListen.add(ergebnisDokumentPerListe.get(liste));
      }
    }

    this.gelosteListen = new ArrayList<>();

    for (Liste liste : customData.getGelosteListen(listen)) {
      if (ergebnisDokumentPerListe.containsKey(liste)) {
        this.gelosteListen.add(ergebnisDokumentPerListe.get(liste));
      }
    }

    Collection<Listenverbindung> listenverbindungen = ergebnisDaten.getListenverbindungen();

    this.beteiligteListenverbindungen = new ArrayList<>();

    for (Listenverbindung listenverbindung : customData.getBeteiligteListenverbindungen(listenverbindungen)) {
      if (ergebnisDokumentPerListenverbindung.containsKey(listenverbindung)) {
        this.beteiligteListenverbindungen.add(ergebnisDokumentPerListenverbindung.get(listenverbindung));
      }
    }

    this.gelosteListenverbindungen = new ArrayList<>();

    for (Listenverbindung listenverbindung : customData.getGelosteListenverbindungen(listenverbindungen)) {
      if (ergebnisDokumentPerListenverbindung.containsKey(listenverbindung)) {
        this.gelosteListenverbindungen.add(ergebnisDokumentPerListenverbindung.get(listenverbindung));
      }
    }

    Gebiet gebietEntity = customData.getGebiet(kandidaturen, listen, listenverbindungen);

    if (gebietEntity == null) {
      this.gebiet = GebietDokument.EMPTY_OBJECT;
    } else {
      this.gebiet = new GebietDokument(coreElectContext, gebietEntity);
    }
  }
}
