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

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);
    }
    var wahldurchfuehrungDb = wahldurchfuehrungDAO.attach(wahldurchfuehrungExtern);

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

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

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

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

    var 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) {
    var 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
    var 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(), () -> isWurzelgebietFreigegeben(wahldurchfuehrung))) {
      praesentationGenerierenEvent.sendChangeEvent();
    }

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

  private boolean isWurzelgebietFreigegeben(Wahldurchfuehrung wahldurchfuehrung) {
    var wurzelgebiet = wahldurchfuehrung.getWurzelgebiet(wahldurchfuehrungsgebietDAO);
    if (wurzelgebiet == null) {
      return false;
    }
    return wurzelgebiet.castTo(Wahldurchfuehrungsgebiet.class).getEntity()
        .getErgebniseingabestatus(wahldurchfuehrung.getErgebniseingangsart().korrespondierendeErgebnisart()).isFreigegeben();
  }

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

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

    var 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) {
    var vorlagen = praesentationVorlageFinder.findeVorlagen(wahldurchfuehrung);
    dokumentVorlageEdit.deleteAll(vorlagen);
  }

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