
package de.ivu.elect.presentation.stimmeingabe;

import java.util.Collection;
import java.util.HashMap;
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.Ergebniseingabestufe;
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;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;

public class StimmeingabeErfassenViewContext extends AbstractStimmeingabeErfassenContext {

  private final Ergebniseingang aktuellerErgebniseingang;

  private final Ergebniseingang letzterErgebniseingangAktuell;

  private final Collection<Stimmeingabe> letzterErgebniseingangAktuellStimmeingaben;

  private final List<Stimmeingabefehler> letzterErgebniseingangAktuellStimmeingabefehler;

  private final Ergebniseingang letzterErgebniseingangAktuellGueltig;

  private final Collection<Stimmeingabe> letzterErgebniseingangAktuellGueltigStimmeingaben;

  private final Ergebniseingang letzterErgebniseingangAktuellVorlaeufig;

  private final Collection<Stimmeingabe> letzterErgebniseingangAktuellVorlaeufigStimmeingaben; // ELECT-8352

  private final Ergebniseingang letzterErgebniseingangErfasst;

  private final Map<Ergebniseingabestufe, Ergebniseingang> letzterErgebniseingangErfasstPerErgebniseingabestufe;

  private final Ergebniseingang vergleichErgebniseingang;

  private final Collection<Stimmeingabe> vergleichErgebniseingangStimmeingaben;

  private final StimmeingabeErfassenViewRequestScopedState requestScopedState;

  private final StimmeingabeKopfzahlErfassenLabelGenerator stimmeingabeKopfzahlErfassenLabelGenerator;

  private final StimmeingabeGruppeStimmenErfassenLabelGenerator stimmeingabeGruppeStimmenErfassenLabelGenerator;

  private final StimmeingabeListenkandidaturStimmenErfassenLabelGenerator stimmeingabeListenkandidaturStimmenErfassenLabelGenerator;

  private final StimmeingabeReferendumOptionStimmenErfassenLabelGenerator stimmeingabeReferendumOptionStimmenErfassenLabelGenerator;

  private final GebietNummerFormatter gebietNummerFormatter;

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

  private final EntityAufStimmzettelDaten entityAufStimmzettelDaten;

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

  public StimmeingabeErfassenViewContext(Ergebniseingang aktuellerErgebniseingang, Ergebniseingang letzterErgebniseingangAktuell, Collection<Stimmeingabe> letzterErgebniseingangAktuellStimmeingaben,
      List<Stimmeingabefehler> letzterErgebniseingangAktuellStimmeingabefehler, Ergebniseingang letzterErgebniseingangAktuellGueltig,
      Collection<Stimmeingabe> letzterErgebniseingangAktuellGueltigStimmeingaben, Ergebniseingang letzterErgebniseingangAktuellVorlaeufig,
      Collection<Stimmeingabe> letzterErgebniseingangAktuellVorlaeufigStimmeingaben, Ergebniseingang vergleichErgebniseingang, Collection<Stimmeingabe> vergleichErgebniseingangStimmeingaben,
      Ergebniseingang letzterErgebniseingangErfasst, Map<Ergebniseingabestufe, Ergebniseingang> letzterErgebniseingangErfasstPerErgebniseingabestufe,
      StimmeingabeErfassenViewRequestScopedState requestScopedState, StimmeingabeKopfzahlErfassenLabelGenerator stimmeingabeKopfzahlErfassenLabelGenerator,
      StimmeingabeGruppeStimmenErfassenLabelGenerator stimmeingabeGruppeStimmenErfassenLabelGenerator,
      StimmeingabeListenkandidaturStimmenErfassenLabelGenerator stimmeingabeListenkandidaturStimmenErfassenLabelGenerator,
      StimmeingabeReferendumOptionStimmenErfassenLabelGenerator stimmeingabeReferendumOptionStimmenErfassenLabelGenerator, GebietNummerFormatter gebietNummerFormatter,
      Supplier<Map<Gruppe, Collection<Wahlvorschlag>>> wahlvorschlaegeInWahlPerGruppeSupplier, EntityAufStimmzettelDaten entityAufStimmzettelDaten,
                                         Function<Gebiet, List<Wahldurchfuehrungsgebiet>> erfasstFuer) {
    super();

    this.aktuellerErgebniseingang = aktuellerErgebniseingang;

    this.letzterErgebniseingangAktuell = letzterErgebniseingangAktuell;
    this.letzterErgebniseingangAktuellStimmeingaben = letzterErgebniseingangAktuellStimmeingaben;
    this.letzterErgebniseingangAktuellStimmeingabefehler = letzterErgebniseingangAktuellStimmeingabefehler;

    this.letzterErgebniseingangAktuellGueltig = letzterErgebniseingangAktuellGueltig;
    this.letzterErgebniseingangAktuellGueltigStimmeingaben = letzterErgebniseingangAktuellGueltigStimmeingaben;

    this.letzterErgebniseingangAktuellVorlaeufig = letzterErgebniseingangAktuellVorlaeufig;
    this.letzterErgebniseingangAktuellVorlaeufigStimmeingaben = letzterErgebniseingangAktuellVorlaeufigStimmeingaben;

    this.vergleichErgebniseingang = vergleichErgebniseingang;
    this.vergleichErgebniseingangStimmeingaben = vergleichErgebniseingangStimmeingaben;

    this.letzterErgebniseingangErfasst = letzterErgebniseingangErfasst;
    this.letzterErgebniseingangErfasstPerErgebniseingabestufe = new HashMap<>(letzterErgebniseingangErfasstPerErgebniseingabestufe);

    this.requestScopedState = requestScopedState;

    this.stimmeingabeKopfzahlErfassenLabelGenerator = stimmeingabeKopfzahlErfassenLabelGenerator;
    this.stimmeingabeGruppeStimmenErfassenLabelGenerator = stimmeingabeGruppeStimmenErfassenLabelGenerator;
    this.stimmeingabeListenkandidaturStimmenErfassenLabelGenerator = stimmeingabeListenkandidaturStimmenErfassenLabelGenerator;
    this.stimmeingabeReferendumOptionStimmenErfassenLabelGenerator = stimmeingabeReferendumOptionStimmenErfassenLabelGenerator;

    this.entityAufStimmzettelDaten = entityAufStimmzettelDaten;

    this.gebietNummerFormatter = gebietNummerFormatter;

    this.wahlvorschlaegeInWahlPerGruppeSupplier = wahlvorschlaegeInWahlPerGruppeSupplier;

    this.erfasstFuer = erfasstFuer;
  }

  @Override
  public Ergebniseingang getErgebniseingang() {
    return aktuellerErgebniseingang;
  }

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

  @Override
  public Collection<Stimmeingabe> getLetzterErgebniseingangAktuellStimmeingaben() {
    return letzterErgebniseingangAktuellStimmeingaben;
  }

  @Override
  public List<Stimmeingabefehler> getLetzterErgebniseingangAktuellStimmeingabefehler() {
    return letzterErgebniseingangAktuellStimmeingabefehler;
  }

  public Ergebniseingang getLetzterErgebniseingangAktuellGueltig() {
    return letzterErgebniseingangAktuellGueltig;
  }

  public Collection<Stimmeingabe> getLetzterErgebniseingangAktuellGueltigStimmeingaben() {
    return letzterErgebniseingangAktuellGueltigStimmeingaben;
  }

  public Ergebniseingang getLetzterErgebniseingangAktuellVorlaeufig() {
    return letzterErgebniseingangAktuellVorlaeufig;
  }

  @Override
  public Collection<Stimmeingabe> getLetzterErgebniseingangAktuellVorlaeufigStimmeingaben() {
    return letzterErgebniseingangAktuellVorlaeufigStimmeingaben;
  }

  public Ergebniseingang getLetzterErgebniseingangErfasst() {
    return letzterErgebniseingangErfasst;
  }

  public Ergebniseingang getLetzterErgebniseingangErfasstInErgebniseingabestufe(Ergebniseingabestufe ergebniseingabestufe) {
    return letzterErgebniseingangErfasstPerErgebniseingabestufe.get(ergebniseingabestufe);
  }

  public Ergebniseingang getVergleichErgebniseingang() {
    return vergleichErgebniseingang;
  }

  @Override
  public String getGebietName() {
    return gebietNummerFormatter.getDarstellung(getWahldurchfuehrungsgebiet());
  }

  @Override
  public Collection<GruppeImGebiet> getGruppenImGebiet() {
    return requestScopedState.getGruppenImGebiet();
  }

  @Override
  public Collection<Stimmeingabe> getVergleichErgebniseingangStimmeingaben() {
    return vergleichErgebniseingangStimmeingaben;
  }

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

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

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

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

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

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

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