package de.ivu.elect.core.exchange.wahlbeteiligung.mapper;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.wahl.boundary.WahlFactory;
import de.ivu.elect.business.wahl.boundary.WahlterminFactory;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahlart;
import de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlaufStatus;
import de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlaufTyp;
import de.ivu.elect.exchange.gebietsbaum.mapper.GebietMapperUtil;
import de.ivu.elect.interfaces.core.GebietReferenz;
import de.ivu.elect.interfaces.was.wahlbeteiligung.WahlbeteiligungExchange;
import de.ivu.elect.interfaces.was.wahlbeteiligung.WahlbeteiligungVerlauf;
import de.ivu.elect.interfaces.was.wahlbeteiligung.WahlbeteiligungVerlaufGebiet;

public class WahlbeteiligungMapper implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  protected transient GebietMapperUtil gebietMapperUtil;

  @Inject
  private transient WahlFactory wahlFactory;

  @Inject
  private transient WahlterminFactory wahlterminFactory;

  public WahlbeteiligungVerlauf mappe(de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlauf from) {
    WahlbeteiligungVerlauf to = new WahlbeteiligungVerlauf();

    to.setWahldatum(from.getWahl().getWahldatum());
    to.setWahlterminNummer(from.getWahl().getWahltermin().getNummer());
    to.setWahlart(from.getWahl().getWahlart().getName());

    to.setName(from.getName());
    to.setBemerkung(from.getBemerkung());
    to.setDatum(from.getDatum());
    to.setStatus(from.getStatus().name());
    to.setTyp(from.getTyp().name());

    for (de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlaufGebiet wahlbeteiligungVerlaufGebiet : from
        .getWahlbeteiligungVerlaufGebietsByWahlbeteiligungVerlauf()) {
      to.getWahlbeteiligungVerlaeufeGebiet().add(mappe(wahlbeteiligungVerlaufGebiet));
    }

    return to;
  }

  public WahlbeteiligungVerlaufGebiet mappe(de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlaufGebiet from) {
    WahlbeteiligungVerlaufGebiet to = new WahlbeteiligungVerlaufGebiet();

    to.setGebietReferenz(gebietMapperUtil.createGebietReferenz(from.getGebiet()));
    to.setProzent(from.getWahlbeteilung());

    return to;
  }

  public de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlauf mappe(WahlbeteiligungVerlauf from, Map<GebietReferenz, Gebiet> gebieteNachReferenz) {
    de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlauf to = new de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlauf();

    Wahl wahl = wahlFactory.create();
    wahl.setWahltermin(wahlterminFactory.create());
    wahl.setWahlart(new Wahlart());
    to.setWahl(wahl);
    wahl.getWahltermin().setWahldatum(from.getWahldatum());
    wahl.getWahltermin().setNummer(from.getWahlterminNummer());

    wahl.getWahlart().setName(from.getWahlart());

    to.setName(from.getName());
    to.setBemerkung(from.getBemerkung());
    to.setDatum(from.getDatum());
    to.setStatus(WahlbeteiligungVerlaufStatus.valueOf(from.getStatus()));
    to.setTyp(WahlbeteiligungVerlaufTyp.valueOf(from.getTyp()));

    for (WahlbeteiligungVerlaufGebiet wahlbeteiligungVerlaufGebiet : from.getWahlbeteiligungVerlaeufeGebiet()) {
      to.addWahlbeteiligungVerlaufGebietByWahlbeteiligungVerlauf(mappe(wahlbeteiligungVerlaufGebiet, gebieteNachReferenz));
    }

    return to;
  }

  public de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlaufGebiet mappe(WahlbeteiligungVerlaufGebiet from, Map<GebietReferenz, Gebiet> gebieteNachReferenz) {
    de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlaufGebiet to = new de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlaufGebiet();
    to.setGebiet(gebietMapperUtil.createGebiet(from.getGebietReferenz(), gebieteNachReferenz));
    to.setWahlbeteilung(from.getProzent());

    return to;
  }

  public WahlbeteiligungExchange mappe(List<de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlauf> wahlbeteiligungVerlaeufe) {

    WahlbeteiligungExchange result = new WahlbeteiligungExchange();
    for (de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlauf wahlbeteiligungVerlauf : wahlbeteiligungVerlaeufe) {
      result.getWahlbeteiligungVerlaeufe().add(mappe(wahlbeteiligungVerlauf));
    }

    return result;
  }

  public List<de.ivu.elect.business.wahlbeteiligung.entity.WahlbeteiligungVerlauf> mappe(WahlbeteiligungExchange wahlbeteiligungExchange) {
    Map<GebietReferenz, Gebiet> gebietReferenzenMap = new HashMap<>();
    return wahlbeteiligungExchange.getWahlbeteiligungVerlaeufe().stream()
        .map(wahlbeteiligungVerlauf -> mappe(wahlbeteiligungVerlauf, gebietReferenzenMap))
        .collect(Collectors.toList());
  }
}
