
package de.ivu.elect.business.wahl.control;

import javax.inject.Inject;
import javax.persistence.NoResultException;

import de.ivu.elect.business.benutzerverwaltung.boundary.RolleDAO;
import de.ivu.elect.business.benutzerverwaltung.entity.Rolle;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.wahl.boundary.WahlartDAO;
import de.ivu.elect.business.wahl.boundary.WahlterminDAO;
import de.ivu.elect.business.wahl.entity.NonUniqueWahlterminUndWahlartUKException;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahlart;
import de.ivu.elect.business.wahl.entity.Wahltermin;

public class WahlCreate extends AbstractWahlCreate {

  @Inject
  protected transient RolleDAO rolleDao;

  @Inject
  protected transient WahlartDAO wahlartDao;

  @Inject
  protected transient WahlterminDAO wahlterminDao;

  @Inject
  protected transient WahlPostCreate wahlPostCreate;

  @Inject
  private transient WahlterminCreate wahlterminCreate;

  public WahlCreate() {
    super();
  }

  @Override
  public void save(Wahl wahl) {
    setzeWahlterminWennSchonPersistentVorhanden(wahl);

    Rolle einsehenRolle = wahl.getEinsehenRolle();

    if (einsehenRolle != null && einsehenRolle.isPersistent()) {
      wahl.setEinsehenRolle(attach(einsehenRolle));
    }

    wahl.setWahlart(attach(wahl.getWahltermin().getMandant(), wahl.getWahlart()));

    if (!wahl.hasFarbe()) {
      wahl.setFarbe(wahl.getWahlart().getFarbe());
    }

    assertUniqueWahlTk(wahl);

    if (!wahl.getWahltermin().isPersistent()) {
      // Wahltermin anlegen, wenn nicht vorhanden
      Wahltermin wahltermin = wahl.getWahltermin();
      wahlterminCreate.save(wahltermin);
    }

    if (wahl.getEinsehenRolle() != null && !wahl.getEinsehenRolle().isPersistent()) {
      wahl.getEinsehenRolle().setMandant(wahl.getMandant());
    }

    super.save(wahl);

    wahlPostCreate.postCreate(wahl);
  }

  private void setzeWahlterminWennSchonPersistentVorhanden(Wahl wahl) {
    // Wenn bereits persistenter Wahltermin, dann diesen nutzen
    if (wahl.getWahltermin().isPersistent()) {
      var attached = attach(wahl.getWahltermin());
      if (attached != null /*ELECTKOM-2433*/) {
        wahl.setWahltermin(attached);
      }
    }

    try {
      wahl.setWahltermin(wahlterminDao.findByUK(wahl.getWahltermin().getWahlterminUK()));
    } catch (NoResultException nre) {
      // erstmal nichts machen
    }
  }

  private void assertUniqueWahlTk(Wahl wahl) {
    if (!isUniqueWahlTk(wahl)) {
      throw new NonUniqueWahlterminUndWahlartUKException();
    }
  }

  private boolean isUniqueWahlTk(Wahl wahl) {
    return !dao.isEntityWithUKPresent(wahl.getWahlUK());
  }

  private Wahlart attach(Mandant mandant, Wahlart wahlart) {
    return wahlartDao.findByName(mandant, wahlart.getName());
  }

  private Wahltermin attach(Wahltermin wahltermin) {
    return wahlterminDao.attach(wahltermin);
  }

  private Rolle attach(Rolle rolle) {
    return rolleDao.attach(rolle);
  }
}
