
package de.ivu.elect.business.wahlvorschlag.boundary;

import java.util.ArrayList;
import java.util.Collection;

import javax.ejb.Stateless;
import javax.inject.Inject;

import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.kandidatur.boundary.ListenkandidaturEdit;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.protokollierung.entity.LoeschProtokollEvent;
import de.ivu.elect.business.wahlvorschlag.control.NonUniqueWahlvorschlagUkException;
import de.ivu.elect.business.wahlvorschlag.control.UniqueWahlvorschlagUkValidator;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.Listenverbindung;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagStatus;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;

@Stateless
public class ListeEdit extends AbstractListeEdit {

  @Inject
  private transient Messages messages;

  @Inject
  private transient WahlvorschlagCommonEdit wahlvorschlagCommonEdit;

  @Inject
  private transient ListenkandidaturEdit listenkandidaturEdit;

  @Inject
  private transient ListenverbindungEdit listenverbindungEdit;

  @Inject
  private transient LoeschProtokollEvent loeschProtokollEvent;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  @Inject
  private transient UniqueWahlvorschlagUkValidator uniqueWahlvorschlagUkValidator;

  public ListeEdit() {
    super();
  }

  @Override
  protected boolean usesMixedTransactionalContexts() {
    // ELECT-945, bspw. verwenden der Validator, der HierarchyBuilder 'einfache' DAOs!
    return true;
  }

  @Override
  public void save(Liste liste) {
    saveAndUpdateGruppeImGebiet(liste, liste.getGruppeImGebiet());
  }

  private void saveAndUpdateGruppeImGebiet(Liste liste, GruppeImGebiet gruppeImGebiet) {
    updateGruppeImGebietPreSave(liste, gruppeImGebiet);

    assertUniqueWahlvorschlagUk(liste);

    super.save(liste);
  }

  private void updateGruppeImGebietPreSave(Liste liste, GruppeImGebiet gruppeImGebiet) {
    wahlvorschlagCommonEdit.updateGruppeImGebietPreSave(liste, gruppeImGebiet);
  }

  private void assertUniqueWahlvorschlagUk(Liste liste) {
    if (!isUniqueWahlvorschlagUk(liste)) {
      throw new NonUniqueWahlvorschlagUkException(liste.getWahlvorschlagUK(), messages);
    }
  }

  private boolean isUniqueWahlvorschlagUk(Liste liste) {
    return uniqueWahlvorschlagUkValidator.isUniqueWahlvorschlagUk(liste);
  }

  public void delete(Collection<Liste> listen) {
    for (Liste liste : new ArrayList<>(listen)) {
      delete(liste);
    }
  }

  @Override
  public void delete(Liste template) {
    Liste liste = getAttachedEntity(template);

    loeschProtokollEvent.sendeLoeschProtokollEvent(liste.getWahl(), liste, "loesch.protokoll.liste", liste.getGruppe().getName(), gebietNummerFormatter.getDarstellung(liste.getGebiet()));

    GruppeImGebiet gruppeImGebiet = liste.getGruppeImGebiet();

    deleteListenverbindung(liste);
    deleteListenkandidaturen(liste);
    deleteWahlvorschlagsPersonen(liste); // ELECT-10755

    wahlvorschlagCommonEdit.updateGruppeImGebietPreDelete(liste, gruppeImGebiet);

    super.delete(liste);

    wahlvorschlagCommonEdit.updateGruppeImGebietPostDelete(gruppeImGebiet);
  }

  private void deleteListenverbindung(Liste liste) {
    Listenverbindung listenverbindung = liste.getListenverbindung();

    if (listenverbindung != null && listenverbindung.getListen().size() <= 2) {
      listenverbindungEdit.delete(listenverbindung);
    }
  }

  private void deleteListenkandidaturen(Liste liste) {
    for (Listenkandidatur listenkandidatur : new ArrayList<>(liste.getListenkandidaturen())) {
      listenkandidaturEdit.delete(listenkandidatur);
    }
  }

  private void deleteWahlvorschlagsPersonen(Liste liste) {
    wahlvorschlagCommonEdit.deleteWahlvorschlagsPersonen(liste);
  }

  public void setStatus(Liste liste, WahlvorschlagStatus wahlvorschlagStatus, String wahlvorschlagStatusBemerkung) {
    wahlvorschlagCommonEdit.setStatus(liste, wahlvorschlagStatus);
  }
}
