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

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

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.mandant.boundary.MandantDAO;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.wahl.control.WahlartCreate;
import de.ivu.elect.business.wahl.entity.AbstractWahlart;
import de.ivu.elect.business.wahl.entity.Wahlart;



@Stateless
public class WahlartCreator {

  private static final Logger LOG = LoggerFactory.getLogger(WahlartCreator.class);

  @Inject
  private transient WahlartDAO wahlartDao;

  @Inject
  private transient WahlartCreate wahlartCreate;

  @Inject
  private transient MandantDAO mandantDAO;

  public WahlartCreator() {
    super();
  }

  public void initWahlartenAlleMandanten() {
    for (Mandant mandant : mandantDAO.findByAll()) {
      if (mandant.getArt().isCustomerMandant()) {
        initWahlarten(mandant);
      }
    }
  }

  public void initWahlarten(Mandant mandant) {
    if (mandant.getArt().isCustomerMandant()) {
      LOG.info("Initialisiere Wahlarten für Mandant: " + mandant.getNummer());
      if (mandant.getArt().isCustomerMandant()) {

        List<Wahlart> vorhandeneWahlarten = findAllWahlarten(mandant);
        Collection<? extends WahlartCreateTemplate> wahlartTemplates = getWahlartCreateTemplates();

        for (WahlartCreateTemplate wahlartTemplate : wahlartTemplates) {
          Wahlart vorhandenWahlart = wahlartVorhanden(wahlartTemplate, vorhandeneWahlarten, wahlartTemplates);
          if (vorhandenWahlart == null) {
            legeWahlartAn(mandant, wahlartTemplate);
          } else {
            aktualisiere(vorhandenWahlart, wahlartTemplate);
          }
        }
      } else {
        LOG.info("Wahlarten für Mandant: " + mandant.getNummer() + " mit Art: " + mandant.getArt() + " werden nicht angelegt");
      }
    }
  }

  private void aktualisiere(Wahlart vorhandeneWahlart, WahlartCreateTemplate wahlartTemplate) {
    // ELECT-8350
    fuelleWahlartVonTEmplate(vorhandeneWahlart, wahlartTemplate);
    if (vorhandeneWahlart.isAttributeChanged()) {
      LOG.info("Bestehende Wahlart aktualisiert: " + vorhandeneWahlart);
    } else {
      LOG.info("Bestehende Wahlart unverändert: " + vorhandeneWahlart);
    }
  }

  private List<Wahlart> findAllWahlarten(Mandant mandant) {
    return wahlartDao.findByAllOrderByName(mandant);
  }

  @Deprecated // Nicht mehr verwenden, Informationen an Entität Wahlart nutzen, wenn nicht vorhanden fragen...
  public Collection<? extends WahlartCreateTemplate> getWahlartCreateTemplates() {
    return new ArrayList<>();
  }

  private Wahlart wahlartVorhanden(WahlartCreateTemplate wahlartTemplate, List<Wahlart> vorhandeneWahlarten, Collection<? extends WahlartCreateTemplate> wahlartTemplates) {
    return vorhandeneWahlarten.stream().filter(wahlart -> wahlartTemplate.equals(wahlart.getCustomWahlartCreateTemplate(wahlartTemplates))).findFirst()
      .orElse(null);
  }


  public Wahlart getWahlart(Mandant mandant, WahlartCreateTemplate wahlartTemplate) {
    Collection<? extends WahlartCreateTemplate> wahlartTemplates = getWahlartCreateTemplates();
    for (Wahlart wahlart : findAllWahlarten(mandant)) {
      if (wahlartTemplate.equals(wahlart.getCustomWahlartCreateTemplate(wahlartTemplates))) {
        return wahlart;
      }
    }

    throw new IllegalStateException("Keine Wahlart gefunden: '" + wahlartTemplate + "'");
  }

  protected void legeWahlartAn(Mandant mandant, WahlartCreateTemplate wahlartTemplate) {
    Wahlart wahlart = Wahlart.createWahlartFromTemplate(wahlartTemplate);
    fuelleWahlartVonTEmplate(wahlart, wahlartTemplate); // immer Aufrufen, damit Methode überschrieben werden kann

    wahlart.setMandant(mandant);
    wahlartCreate.save(wahlart);

    LOG.info("Wahlart '" + wahlart.getName() + "' angelegt");
  }

  protected void fuelleWahlartVonTEmplate(Wahlart wahlart, WahlartCreateTemplate wahlartTemplate) {
    AbstractWahlart.fillWahlartFromTemplate(wahlart, wahlartTemplate);
  }
}
