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

import static de.ivu.elect.jee.entity.EntityUtil.castTo;
import static org.apache.commons.lang3.StringUtils.isBlank;

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

import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.NlPolitischeGruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.gruppeimgebiet.boundary.GruppeImGebietExtendedDAO;
import de.ivu.elect.business.stimmzettel.boundary.EntityAufStimmzettelDatenExtendedDAOFactory;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahlvorschlag.boundary.ListeDAO;
import de.ivu.elect.business.wahlvorschlag.boundary.NlListeEdit;
import de.ivu.elect.business.wahlvorschlag.boundary.WahlvorschlagExtendedDAO;

@Stateless
@Specializes
public class NlGruppeEdit extends GruppeEdit {

  @Inject
  protected transient EntityAufStimmzettelDatenExtendedDAOFactory entityAufStimmzettelDatenExtendedDAOFactory;

  @Inject
  protected transient GruppeImGebietExtendedDAO gruppeImGebietExtendedDAO;

  @Inject
  protected transient WahlvorschlagExtendedDAO wahlvorschlagExtendedDAO;

  @Inject
  protected transient ListeDAO listeDAO;

  @Inject
  protected transient NlListeEdit nlListeEdit;

  public NlGruppeEdit() {
    super();
  }

  @Override
  public void save(Gruppe gruppe) {
    saveIncludingNameUpdate(gruppe);
  }

  public void saveNameAbgelehnt(Gruppe gruppe, String nameAbgelehntBemerkung) {
    saveNameAbgelehnt(gruppe, true, nameAbgelehntBemerkung);
  }

  public void saveNameZulaessig(Gruppe gruppe) {
    saveNameAbgelehnt(gruppe, false, "");
  }

  // ELECT-10160
  private void saveNameAbgelehnt(Gruppe gruppe, boolean nameAbgelehnt, String nameAbgelehntBemerkung) {
    saveIncludingNameUpdate(gruppe);

    if (gruppe.isPolitischeGruppe()) {
      NlPolitischeGruppe nlPolitischeGruppe = new NlPolitischeGruppe(castTo(gruppe, PolitischeGruppe.class));

      if (nameAbgelehnt) {
        nlPolitischeGruppe.markNameAbgelehnt(getEntityAufStimmzettelDaten(), nameAbgelehntBemerkung);
      } else {
        nlPolitischeGruppe.markNameZulaessig();
      }
    }

    saveIncludingNameUpdate(gruppe);
  }

  private void saveIncludingNameUpdate(Gruppe gruppe) {
    if (gruppe.isPolitischeGruppe()) {
      NlPolitischeGruppe nlPolitischeGruppe = new NlPolitischeGruppe(castTo(gruppe, PolitischeGruppe.class));

      String name = nlPolitischeGruppe.getName();

      // ELECT-9975 Gruppenname und Wahlvorschlagsbezeichner synchronisieren
      gruppeImGebietExtendedDAO.findByWahlAndGruppe(nlPolitischeGruppe.getWahl(), gruppe).forEach(gruppeImGebiet -> {
        gruppeImGebiet.setName(name);
        gruppeImGebiet.setKurzname(name);
      });

      wahlvorschlagExtendedDAO.findByGruppe(gruppe).forEach(wahlvorschlag -> {
        wahlvorschlag.setKennwort(name);
        wahlvorschlag.setKurzname(name);
      });

      // ELECT-10129
      if (isBlank(nlPolitischeGruppe.getNameInitial())) {
        nlPolitischeGruppe.setNameInitial(name);
      }
    }

    super.save(gruppe);
  }

  @Override
  public void delete(Gruppe template) {
    deleteIncludingListen(template);
  }

  public void deleteIncludingListen(Gruppe template) {
    listeDAO.findByGruppe(template).forEach(nlListeEdit::deleteExcludingGruppe); // ELECT-10181

    dao.flush();
    dao.clear();

    super.delete(template);
  }

  public void deleteExcludingListen(Gruppe template) {
    super.delete(template);
  }

  protected EntityAufStimmzettelDaten getEntityAufStimmzettelDaten() {
    return entityAufStimmzettelDatenExtendedDAOFactory.getEntityAufStimmzettelDaten();
  }
}
