
package de.ivu.elect.was.exchange.wahl;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import de.ivu.elect.business.fremdkandidatur.entity.Fremdkandidatur;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.kandidatur.entity.Ersatzkandidatur;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.veranstaltung.entity.Veranstaltung;
import de.ivu.elect.business.wahl.boundary.WahldurchfuehrungFactory;
import de.ivu.elect.business.wahl.entity.WahlartSitzberechnungsalgorithmus;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungAuswertung;
import de.ivu.elect.interfaces.core.PersonReferenz;
import de.ivu.elect.interfaces.core.VeranstaltungReferenz;
import de.ivu.elect.interfaces.core.Wahl;
import de.ivu.elect.was.exchange.wahl.mapper.WasHelperMapper;
import de.ivu.elect.was.exchange.wahlbeteiligung.mapper.WasWahlbeteiligungMapper;

public class WasWahlExternInternMapper extends AbstractWahlExternInternMapper<Wahldurchfuehrung> {

  @Inject
  private transient WahldurchfuehrungFactory wahldurchfuehrungFactory;

  @Inject
  private transient WasWahlbeteiligungMapper wasWahlbeteiligungMapper;

  @Inject
  private transient WasHelperMapper wasHelperMapper;

  public WasWahlExternInternMapper() {
    super();
  }

  @Override
  protected Map<PersonReferenz, Fremdkandidatur> mapFremdkandidaturen(Wahl wahlExtern, Map<VeranstaltungReferenz, Veranstaltung> veranstaltungInternPerReferenzExtern) {
    return Collections.emptyMap();
  }

  @Override
  protected Wahldurchfuehrung createEmptyWahlobject() {
    return wahldurchfuehrungFactory.create();
  }

  @Override
  protected void mapWahl(Wahl wahlExtern, Wahldurchfuehrung wahlIntern) {
    super.mapWahl(wahlExtern, wahlIntern);

    de.ivu.elect.interfaces.core.Wahldurchfuehrung wahldurchfuehrungExtern = wahlExtern.getWahldurchfuehrung();

    if (wahldurchfuehrungExtern != null) {
      wahlIntern.setSitzberechnungsalgorithmus(WahlartSitzberechnungsalgorithmus.fromId(wahldurchfuehrungExtern.getSitzberechnungsalgorithmus()));
      wahlIntern.setErgebniseingangsart(wasHelperMapper.mappe(wahldurchfuehrungExtern.getErgebniseingangsart()));
    } else {
      wahlIntern.setSitzberechnungsalgorithmus(null);
    }

    if (wahlExtern.getWahlbeteiligungExchange() != null) {
      List<WahlbeteiligungAuswertung> wahlbeteiligungAuswertungs = wasWahlbeteiligungMapper.mappeAuswertungen(wahlExtern.getWahlbeteiligungExchange());
      wahlIntern.addAdditionalData("WahlbeteiligungAuswertung", wahlbeteiligungAuswertungs); // siehe de.ivu.elect.business.wahl.boundary.WasWahlImporter.anlegenWennNichtVorhanden
    }
  }

  @Override
  protected boolean isKandidaturInternZuUebernehmen(Kandidatur kandidaturIntern) {
    return /* ELECT-8948 */ isWusWasZusammen() || !isErsatzbewerberOrErsatzkandidaturForErsatzbewerber(kandidaturIntern);
  }

  /*
   * NOTE ELECTMUC-700, dass Ersatzbewerber (einer Listenkandidatur), die nur während der Zulassung eines Wahlvorschlages im WUS eine Rolle spielen, nicht ins WAS zu übernehmen sind, da für diese
   * demnach nie Stimmen zu erfassen sind.
   */
  private boolean isErsatzbewerberOrErsatzkandidaturForErsatzbewerber(Personendaten personendaten) {
    if (personendaten.isInstanceOf(Ersatzkandidatur.class)) {
      return isErsatzbewerberOrErsatzkandidaturForErsatzbewerber(personendaten.castTo(Ersatzkandidatur.class).getEntity().getUebergeordneteKandidatur());
    }

    return personendaten.isInstanceOf(Listenkandidatur.class) && personendaten.castTo(Listenkandidatur.class).getEntity().isListenkandidaturMarkiertAlsErsatzkandidatur();
  }

  @Override
  protected void postMappeGruppenImGebiet(GruppeImGebiet gruppeImGebietIntern, de.ivu.elect.interfaces.core.GruppeImGebiet gruppeImGebietExtern) {
    super.postMappeGruppenImGebiet(gruppeImGebietIntern, gruppeImGebietExtern);

    // ELECTKOM-183 nur beim reinen WAS
    if (isNurWas() && gruppeImGebietIntern.getVorgegebenePosition() == null) {
      Long stimmzettelPosition = gruppeImGebietExtern.getPosition();

      if (stimmzettelPosition != null) {
        gruppeImGebietIntern.setVorgegebenePosition(stimmzettelPosition); // Einfach alle Positionen fixieren im WAS einfacher, da sich nichts mehr ändert...
        gruppeImGebietIntern.setRelativePosition(stimmzettelPosition); // Einfach alle Positionen fixieren im WAS einfacher, da sich nichts mehr ändert...
      }
    }
  }
}
