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

import java.util.List;

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

import org.apache.commons.lang3.StringUtils;
import org.primefaces.model.file.UploadedFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.dokumente.boundary.DokumentVorlageEdit;
import de.ivu.elect.business.dokumente.control.DokumentVorlageCreate;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageAnlageArt;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.gebietsbaum.boundary.WahldurchfuehrungsgebietDAO;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.internet.control.PraesentationVorlageFinder;
import de.ivu.elect.business.internet.entity.PraesentationGenerierenEvent;
import de.ivu.elect.business.internet.entity.PraesentationKonfiguration;
import de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte;
import de.ivu.elect.business.konfiguration.entity.KonfigurationLoader;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.praesentation.entity.PraesentationAutomatischenExportAnstossen;
import de.ivu.elect.business.praesentation.entity.PraesentationBereitstellen;
import de.ivu.elect.business.praesentation.entity.PraesentationErfassungsgebieteZurueckhalten;
import de.ivu.elect.business.wahl.boundary.WahldurchfuehrungDAO;
import de.ivu.elect.business.wahl.entity.WahlParameterLoader;
import de.ivu.elect.business.wahl.entity.WahlParameterWerte;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;


import static de.ivu.elect.business.wahl.entity.WahlParameterWerte.PREASENTATIION_ERFASSUNGSGEBIETE_PRO_WAHLGEBIET_NOTWENDIG;

@Stateless
public class PraesentationKonfigurieren {

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

  public static final DokumentVorlageArt DOKUMENT_VORLAGE_ART_EXPECTED = DokumentVorlageArt.INTERNET_PREASENTATION_VELOCITY_TEMPLATES;

  @Inject
  private transient DokumentVorlageCreate dokumentVorlageCreate;

  @Inject
  private transient DokumentVorlageEdit dokumentVorlageEdit;

  @Inject
  private transient KonfigurationLoader konfigurationLoader;

  @Inject
  private transient PraesentationGenerierenEvent praesentationGenerierenEvent;

  @Inject
  private transient WahldurchfuehrungDAO wahldurchfuehrungDAO;

  @Inject
  private transient PraesentationVorlageFinder praesentationVorlageFinder;

  @Inject
  private transient InternetPraesentationErmittler internetPraesentationErmittler;

  @Inject
  private transient WahlParameterLoader wahlParameterLoader;

  @Inject
  private transient WahldurchfuehrungsgebietDAO wahldurchfuehrungsgebietDAO;

  public PraesentationKonfigurieren() {
    super();
  }

  public PraesentationKonfiguration getPraesentationKonfiguration(Wahldurchfuehrung wahldurchfuehrungExtern) {
    if (wahldurchfuehrungExtern==null){
      return new PraesentationKonfiguration(false, "", null, 0, false, null, null, PraesentationErfassungsgebieteZurueckhalten.NICHT_ZURUECKHALTEN,
          PraesentationAutomatischenExportAnstossen.DEAKTIVIERT, "", PraesentationBereitstellen.DEAKTIVIERT);
    }
    Wahldurchfuehrung wahldurchfuehrungDb = wahldurchfuehrungDAO.attach(wahldurchfuehrungExtern);

    String praesentationUrl = wahlParameterLoader.resolveStringValue(wahldurchfuehrungDb, WahlParameterWerte.PREASENTATIION_URL);
    PraesentationBereitstellen praesentationBereitstellen = wahlParameterLoader
        .resolveEnumValue(wahldurchfuehrungDb, WahlParameterWerte.PREASENTATIION_STATUS, PraesentationBereitstellen.class);

    Long praesentationErfassungsgebieteNotwendig = wahlParameterLoader.resolveLongValue(wahldurchfuehrungDb, PREASENTATIION_ERFASSUNGSGEBIETE_PRO_WAHLGEBIET_NOTWENDIG);

    PraesentationErfassungsgebieteZurueckhalten praesentationErfassungsgebieteZurueckhalten = wahlParameterLoader
        .resolveEnumValue(wahldurchfuehrungDb, WahlParameterWerte.PREASENTATIION_ERFASSUNGSGEBIETE_ZURUECKHALTEN,
            PraesentationErfassungsgebieteZurueckhalten.class);

    PraesentationAutomatischenExportAnstossen praesentationAutomatischenExportAnstossen = wahlParameterLoader
        .resolveEnumValue(wahldurchfuehrungDb, WahlParameterWerte.PREASENTATIION_AUTOMATISCHEN_EXPORT_ANSTOSSEN,
            PraesentationAutomatischenExportAnstossen.class);

    Mandant mandant = wahldurchfuehrungDb.getMandant();
    return new PraesentationKonfiguration(
        konfigurationLoader.resolveBooleanValue(ElectKonfigurationWerte.PRAESENTATION_EXPORT_INTERNET_AKTIVIERT) && internetPraesentationErmittler.getInternetPraesentationTyp().isPraesentationVerfuegbar()
        , getAusgabeverzeichnis(mandant),
        wahldurchfuehrungDb.getPk(),
        konfigurationLoader.resolveIntegerValue(ElectKonfigurationWerte.PRAESENTATION_EXPORT_INTERNET_MINIMALE_PAUSE_IN_SEKUNDEN),
        konfigurationLoader.resolveBooleanValue(ElectKonfigurationWerte.PRAESENTATION_EXPORT_ALS_ZIP_DATEI),
        bestimmeVorlage(wahldurchfuehrungDb),
            praesentationErfassungsgebieteNotwendig,
        praesentationErfassungsgebieteZurueckhalten,
        praesentationAutomatischenExportAnstossen, praesentationUrl, praesentationBereitstellen);
  }

  @Nullable
  private DokumentVorlage bestimmeVorlage(Wahldurchfuehrung wahldurchfuehrung) {
    List<DokumentVorlage> vorlagen = praesentationVorlageFinder.findeVorlagen(wahldurchfuehrung);

    if (vorlagen.size() == 1) {
      return vorlagen.get(0);
    }

    return null;
  }

  public String getAusgabeverzeichnis(Mandant mandant) {
    return konfigurationLoader.resolveStringValue(ElectKonfigurationWerte.PRAESENTATION_EXPORT_ABLAGEVERZEICHNIS);
  }

  public void savePraesentationKonfiguration(PraesentationKonfiguration praesentationKonfiguration, UploadedFile uploadedFile) {
    // ELECT-2163
    Wahldurchfuehrung wahldurchfuehrung = wahldurchfuehrungDAO.findByPrimaryKey(praesentationKonfiguration.getWahlPK());

    wahlParameterLoader.getParameter(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_URL).setWert(praesentationKonfiguration.getPraesentationUrl());

    // ELECT-4019
    wahlParameterLoader.getParameter(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_STATUS)
        .setWert(praesentationKonfiguration.getPraesentationBereitstellen().name());


    wahlParameterLoader.getParameter(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_ERFASSUNGSGEBIETE_PRO_WAHLGEBIET_NOTWENDIG).setWert(longToString(praesentationKonfiguration.getPraesentationErfassungsgebieteNotwendig()));
    wahlParameterLoader.getParameter(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_ERFASSUNGSGEBIETE_ZURUECKHALTEN).setWert(praesentationKonfiguration.getPraesentationErfassungsgebieteZurueckhalten().name());
    wahlParameterLoader.getParameter(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_AUTOMATISCHEN_EXPORT_ANSTOSSEN).setWert(praesentationKonfiguration.getPraesentationAutomatischenExportAnstossen().name());


    //  ELECT-2165
    if (praesentationKonfiguration.getPraesentationBereitstellen().isAktiviert(wahldurchfuehrung.getErgebniseingangsart().korrespondierendeErgebnisart()
            , () -> wahldurchfuehrung.getWurzelgebiet(wahldurchfuehrungsgebietDAO).castTo(Wahldurchfuehrungsgebiet.class).getEntity()
                .getErgebniseingabestatus(wahldurchfuehrung.getErgebniseingangsart().korrespondierendeErgebnisart()).isFreigegeben())) {
      praesentationGenerierenEvent.sendChangeEvent();
    }

    if (uploadedFile != null) {
      LOG.info("Neue Dokumentvorlage für Internetpräsentation");
      createDokumentVorlage(wahldurchfuehrung, uploadedFile);
    }
  }

  @Nullable
  private String longToString(Long l) {
    if (l==null){
      return null;
    }
    return Long.toString(l);
  }

  private void createDokumentVorlage(Wahldurchfuehrung wahldurchfuehrung, UploadedFile uploadedFile) {
    loescheVorhandene(wahldurchfuehrung);

    DokumentVorlage dokumentVorlage = new DokumentVorlage();
    dokumentVorlage.setAnlageArt(DokumentVorlageAnlageArt.EINZEL_DATEI);
    dokumentVorlage.setDokumentVorlageArt(DOKUMENT_VORLAGE_ART_EXPECTED);
    dokumentVorlage.setName(DokumentVorlageArt.getDokumentVorlageName(uploadedFile.getFileName(), DOKUMENT_VORLAGE_ART_EXPECTED));

    dokumentVorlageCreate.save(dokumentVorlage, uploadedFile, wahldurchfuehrung, wahldurchfuehrung.getWahltermin());

  }

  private void loescheVorhandene(Wahldurchfuehrung wahldurchfuehrung) {
    List<DokumentVorlage> vorlagen = praesentationVorlageFinder.findeVorlagen(wahldurchfuehrung);
    dokumentVorlageEdit.deleteAll(vorlagen);
  }

  public Boolean isVerzeichnisKonfiguriert(Mandant mandant) {
    return StringUtils.isNotEmpty(getAusgabeverzeichnis(mandant));
  }
}
