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

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import de.ivu.document.generator.template.annotations.DocumentComplexField;
import de.ivu.document.generator.template.annotations.DocumentRepeat;
import de.ivu.elect.business.ergebnis.control.ErgebnisDaten;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.internet.control.GebietUndStimmabgabeart;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.dokumente.CoreElectContext;
import de.ivu.elect.dokumente.kandidatur.KandidaturCoreDaten;

// ELECTMUC-173
public class GebietMitDetails extends GebietMitStimmenDocument {

  private static final long serialVersionUID = 1L;

  @DocumentComplexField("Wahlgebiet-Uebergeordnet")
  public final GebietMitStimmenDocument wahlgebietUebergeordnet; // ELECT-10412

  @DocumentComplexField("Quorum-Wahlberechtigte")
  public final ErgebnisQuorumDocument quorumWahlberechtigte; // ELECT-13229

  @DocumentRepeat(value = "PolitischeGruppenErgebnisse", elementClass = PolitischeGruppenErgebnisAufGebiet.class, itemName = "politischeGruppenErgebnis")
  public final List<PolitischeGruppenErgebnisAufGebiet> politischeGruppenErgebnis;

  @DocumentRepeat(value = "PolitischeGruppenErgebnisseAbsoluteMehrheit", elementClass = PolitischeGruppenErgebnisAufGebiet.class, itemName = "politischeGruppenErgebnis")
  public final List<PolitischeGruppenErgebnisAufGebiet> politischeGruppenErgebnisAbsoluteMehrheit; // ELECT-13725

  @DocumentRepeat(value = "ReferendumVorlagenErgebnisse", elementClass = ReferendumVorlageMitStimmergebnissenDocument.class, itemName = "referendumVorlagenErgebnis")
  public final List<ReferendumVorlageMitStimmergebnissenDocument> referendumVorlagenErgebnis;

  @DocumentComplexField("GueltigeErgebnisse")
  public final GruppenErgebnisAufGebiet gueltigeErgebnisse;

  @DocumentComplexField("UngueltigeErgebnisse")
  public final GruppenErgebnisAufGebiet ungueltigeErgebnisse;

  // ELECT-3581 Listenkandidaten sortiert nach Alphabet sind für DD im Fall der Migrationsbeiratswahl interessant...
  @DocumentRepeat(value = "ListenkandidaturenAlphabetisch", elementClass = KandidaturMitStimmergebnissenDocument.class, itemName = "listenkandidatur")
  public final List<KandidaturMitStimmergebnissenDocument> listenkandidaturenAlphabetisch;

  public GebietMitDetails(CoreElectContext coreElectContext, ErgebnisDaten ergebnisDaten, GebietUndStimmabgabeart gebietUndStimmabgabeart, GebietMitStimmenDocument wahlgebietUebergeordnet,
      KandidaturCoreDaten kandidaturCoreDaten, Map<Kandidatur, KandidaturMitStimmergebnissenDocument> ergebnisDokumentPerKandidatur) {
    super(coreElectContext, ergebnisDaten, gebietUndStimmabgabeart);

    this.wahlgebietUebergeordnet = wahlgebietUebergeordnet;

    this.quorumWahlberechtigte = new ErgebnisQuorumDocument(coreElectContext, ergebnisDaten.getErgebnisDatenQuorumWahlberechtigte(), gebietUndStimmabgabeart);

    GruppeErgebnisBuilder gruppeErgebnisBuilder = new GruppeErgebnisBuilder(coreElectContext, ergebnisDaten, gebietUndStimmabgabeart, kandidaturCoreDaten);

    this.politischeGruppenErgebnis = gruppeErgebnisBuilder.erstellePolitischeGruppenErgebisse();
    this.politischeGruppenErgebnisAbsoluteMehrheit = gruppeErgebnisBuilder.getPolitischeGruppenErgebisAbsoluteMehrheit();

    this.gueltigeErgebnisse = gruppeErgebnisBuilder.erstelleGueltigeErgebnisse();
    this.ungueltigeErgebnisse = gruppeErgebnisBuilder.erstelleUngueltigeErgebnisse();

    List<Listenkandidatur> listenkandidaturen = ergebnisDaten.getListenkandidaturenAufGebiet(gebietUndStimmabgabeart.getWahldurchfuehrungsgebiet());

    this.listenkandidaturenAlphabetisch = GebietMitListenDocument.bestimmeListenkandidaturenAlphabetisch(listenkandidaturen, ergebnisDokumentPerKandidatur);

    this.referendumVorlagenErgebnis = erstelleReferendumVorlagenErgebnis(coreElectContext, ergebnisDaten, gebietUndStimmabgabeart);
  }

  private List<ReferendumVorlageMitStimmergebnissenDocument> erstelleReferendumVorlagenErgebnis(CoreElectContext coreElectContext, ErgebnisDaten ergebnisDaten,
      GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    List<ReferendumVorlageMitStimmergebnissenDocument> result = new LinkedList<>();

    Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet = gebietUndStimmabgabeart.getWahldurchfuehrungsgebiet();

    List<GruppeImGebiet> referendumVorlagenImGebiet = ergebnisDaten.getWahldaten().getReferendumVorlagenSortiertNachPositionAufGebiet(wahldurchfuehrungsgebiet).stream() //
        .map(referendumVorlage -> ergebnisDaten.getGruppeImGebiet(referendumVorlage, wahldurchfuehrungsgebiet)) //
        .collect(Collectors.toList());

    for (int i = 0; i < referendumVorlagenImGebiet.size(); i++) {
      result.add(new ReferendumVorlageMitStimmergebnissenDocument(coreElectContext, ergebnisDaten, gebietUndStimmabgabeart, referendumVorlagenImGebiet.get(i), i + 1L));
    }

    return result;
  }
}
