
package de.ivu.elect.dokumente.stimmeingabe;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.stimmeingabe.control.AbstractStimmeingabeErfassenContext;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeGruppeStimmenErfassenLabelGenerator;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeKopfzahlErfassenLabelGenerator;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeListenkandidaturStimmenErfassenLabelGenerator;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeReferendumOptionStimmenErfassenLabelGenerator;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabe;
import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabefehler;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;

class WasStimmeingabeDocumentByErgebniseingangExportContext extends AbstractStimmeingabeErfassenContext {

  private final Ergebniseingang persistenterErgebniseingang;

  private final StimmeingabeKopfzahlErfassenLabelGenerator stimmeingabeKopfzahlErfassenLabelGenerator;

  private final StimmeingabeGruppeStimmenErfassenLabelGenerator gruppeStimmenErfassenLabelGenerator;

  private final StimmeingabeListenkandidaturStimmenErfassenLabelGenerator listenkandidaturStimmenErfassenLabelGenerator;

  private final StimmeingabeReferendumOptionStimmenErfassenLabelGenerator referendumOptionStimmenErfassenLabelGenerator;

  private final Supplier<Map<Gruppe, Collection<Wahlvorschlag>>> wahlvorschlaege;

  private final EntityAufStimmzettelDaten entityAufStimmzettelDaten;

  private Ergebniseingang transienterErgebniseingang;

  private Collection<GruppeImGebiet> gruppenImGebiet;

  private final Function<Gebiet, List<Wahldurchfuehrungsgebiet>> erfasstFuer;

  public WasStimmeingabeDocumentByErgebniseingangExportContext(Ergebniseingang persistenterErgebniseingang, StimmeingabeKopfzahlErfassenLabelGenerator stimmeingabeKopfzahlErfassenLabelGenerator,
      StimmeingabeGruppeStimmenErfassenLabelGenerator gruppeStimmenErfassenLabelGenerator, StimmeingabeListenkandidaturStimmenErfassenLabelGenerator listenkandidaturStimmenErfassenLabelGenerator,
      StimmeingabeReferendumOptionStimmenErfassenLabelGenerator referendumOptionStimmenErfassenLabelGenerator, Supplier<Map<Gruppe, Collection<Wahlvorschlag>>> wahlvorschlaege,
      EntityAufStimmzettelDaten entityAufStimmzettelDaten, Function<Gebiet, List<Wahldurchfuehrungsgebiet>> erfasstFuer) {
    super();

    this.persistenterErgebniseingang = persistenterErgebniseingang;
    this.stimmeingabeKopfzahlErfassenLabelGenerator = stimmeingabeKopfzahlErfassenLabelGenerator;
    this.gruppeStimmenErfassenLabelGenerator = gruppeStimmenErfassenLabelGenerator;
    this.listenkandidaturStimmenErfassenLabelGenerator = listenkandidaturStimmenErfassenLabelGenerator;
    this.referendumOptionStimmenErfassenLabelGenerator = referendumOptionStimmenErfassenLabelGenerator;
    this.wahlvorschlaege = wahlvorschlaege;
    this.entityAufStimmzettelDaten = entityAufStimmzettelDaten;
    this.erfasstFuer = erfasstFuer;
  }

  @Override
  public Ergebniseingang getErgebniseingang() {
    if (transienterErgebniseingang == null) {
      // nicht benötigt, aber Eigenschaften werden abgefragt
      transienterErgebniseingang = new Ergebniseingang();
      persistenterErgebniseingang.copyEntityAttributesUsingSetter(transienterErgebniseingang);
      transienterErgebniseingang.setWahldurchfuehrungsgebiet(persistenterErgebniseingang.getWahldurchfuehrungsgebiet());
    }

    return transienterErgebniseingang;
  }

  @Override
  public Ergebniseingang getLetzterErgebniseingangAktuell() {
    return persistenterErgebniseingang;
  }

  @Override
  public Collection<Stimmeingabe> getLetzterErgebniseingangAktuellStimmeingaben() {
    return persistenterErgebniseingang.getStimmeingaben();
  }

  @Override
  public Collection<Stimmeingabe> getVergleichErgebniseingangStimmeingaben() {
    return Collections.emptyList();
  }

  @Override
  public Collection<Stimmeingabe> getLetzterErgebniseingangAktuellVorlaeufigStimmeingaben() {
    return Collections.emptyList(); // ELECT-8352 spielt hier keine Rolle
  }

  @Override
  public Collection<GruppeImGebiet> getGruppenImGebiet() {
    if (gruppenImGebiet == null) {
      gruppenImGebiet = new HashSet<>();

      for (Stimmeingabe stimmeingabe : getLetzterErgebniseingangAktuellStimmeingaben()) {
        gruppenImGebiet.add(stimmeingabe.getGruppeImGebiet());
      }
    }

    return gruppenImGebiet;
  }

  @Override
  public List<Stimmeingabefehler> getLetzterErgebniseingangAktuellStimmeingabefehler() {
    return Collections.emptyList();
  }

  @Override
  public EntityAufStimmzettelDaten getEntityAufStimmzettelDaten() {
    return entityAufStimmzettelDaten;
  }

  @Override
  public StimmeingabeKopfzahlErfassenLabelGenerator getStimmeingabeKopfzahlErfassenLabelGenerator() {
    return stimmeingabeKopfzahlErfassenLabelGenerator;
  }

  @Override
  public StimmeingabeGruppeStimmenErfassenLabelGenerator getGruppeStimmenErfassenLabelGenerator() {
    return gruppeStimmenErfassenLabelGenerator;
  }

  @Override
  public StimmeingabeListenkandidaturStimmenErfassenLabelGenerator getListenkandidaturStimmenErfassenLabelGenerator() {
    return listenkandidaturStimmenErfassenLabelGenerator;
  }

  @Override
  public StimmeingabeReferendumOptionStimmenErfassenLabelGenerator getReferendumOptionStimmenErfassenLabelGenerator() {
    return referendumOptionStimmenErfassenLabelGenerator;
  }

  @Override
  public Supplier<Map<Gruppe, Collection<Wahlvorschlag>>> getWahlvorschlaege() {
    return wahlvorschlaege;
  }

  @Override
  public Function<Gebiet, List<Wahldurchfuehrungsgebiet>> getErfasstFuer() {
    return erfasstFuer;
  }
}
