
package de.ivu.elect.presentation.exchange;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.dokumente.boundary.DokumentVorlageExtendedDAO;
import de.ivu.elect.business.dokumente.control.ElectDokumentContext;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumProperty;
import de.ivu.elect.presentation.dokumente.DokumentVorlageProperty;
import de.ivu.elect.presentation.dokumente.ElectDokumentContextGenerator;

public abstract class AbstractDokumentExportSearchView<T, C> extends AbstractExportSearchView<T, C> {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient DokumentVorlageExtendedDAO dokumentVorlageExtendedDAO;

  @Inject
  private transient ElectDokumentContextGenerator electDokumentContextGenerator;

  private DokumentVorlageProperty dokumentVorlageProperty;

  protected List<DokumentVorlage> dokumentVorlagen;

  private FileType dokumentTargetFileType;

  protected List<FileType> dokumentTargetFileTypes;

  protected AbstractDokumentExportSearchView() {
    super();
  }

  public abstract DokumentVorlageArt getDokumentVorlageArt();

  public void preRenderView() {
    if (isDokumentVorlageRequired()) {
      if (!hasDokumentVorlagen()) {
        addErrorMessage("dokument.vorlage.nicht.hinterlegt", getMessage(getDokumentVorlageArt()));
      } else if (getDokumentVorlageProperty().getValue() == null) {
        getDokumentVorlageProperty().setValue(getDokumentVorlagen().get(0));
      }
    }
  }

  protected boolean hasDokumentVorlagen() {
    return !getDokumentVorlagen().isEmpty();
  }

  @Override
  public boolean isExportParameterModelPresent() {
    return true;
  }

  @Override
  protected void addProperties(FormBuilder formBuilder) {
    if (isDokumentVorlageRequired()) {
      formBuilder.addProperty(getDokumentVorlageProperty());
    }

    List<FileType> dokumentTargetFileTypes = getDokumentTargetFileTypes();

    if (dokumentTargetFileTypes.size() > 1) {
      formBuilder.addProperty(
          new LambdaEnumProperty<>(getMessage("dokument.erzeugen.zieldatei.typ"), false, this::setDokumentTargetFileType, this::getDokumentTargetFileType, FileType.class, dokumentTargetFileTypes));
    }
  }

  protected DokumentVorlageProperty getDokumentVorlageProperty() {
    if (dokumentVorlageProperty == null) {
      dokumentVorlageProperty = new DokumentVorlageProperty(getDokumentVorlagen());
    }

    return dokumentVorlageProperty;
  }

  protected DokumentVorlage getDokumentVorlage() {
    // HINT: Dokumentvorlagen können nur ausgewählt worden sein, wenn das DynaForm-Modell auch gebaut wurde.
    //       Nicht verfrüht die Properties zusammenbauen, sonst sind diese ohne Wahl und damit ohne Dokumentvorlagen!
    if (isExportParameterModelCreated()) {
      return getDokumentVorlageProperty().getValue();
    }

    return null;
  }

  public List<DokumentVorlage> getDokumentVorlagen() {
    if (isWahlSelected()) {
      if (dokumentVorlagen == null) {
        dokumentVorlagen = dokumentVorlageExtendedDAO.findByWahlAndArtOrderByName(getSelectedWahl(), getDokumentVorlageArt());
      }

      return dokumentVorlagen;
    }

    return Collections.emptyList();
  }

  protected void resetDokumentVorlage() {
    dokumentVorlageProperty = null;
    dokumentVorlagen = null;
    dokumentTargetFileType = null;
    dokumentTargetFileTypes = null;
  }

  protected abstract boolean isDokumentVorlageRequired();

  private FileType getDokumentTargetFileType() {
    return dokumentTargetFileType;
  }

  private void setDokumentTargetFileType(FileType dokumentTargetFileType) {
    this.dokumentTargetFileType = dokumentTargetFileType;
  }

  protected List<FileType> getDokumentTargetFileTypes() {
    if (dokumentTargetFileTypes == null) {
      List<FileType> fileTypes = new ArrayList<>(getSupportedFileTypes());
      fileTypes.removeIf(fileType -> !fileType.isOpenDocumentFile());

      if (!fileTypes.contains(FileType.ODT)) {
        fileTypes.add(FileType.ODT);
      }

      fileTypes.add(FileType.PDF);

      dokumentTargetFileTypes = fileTypes;
    }

    return dokumentTargetFileTypes;
  }

  protected ElectDokumentContext createElectDokumentContext() {
    return electDokumentContextGenerator.createElectDokumentContext();
  }

  @Override
  public boolean isBtnExportierenDisabled() {
    return super.isBtnExportierenDisabled() || isDokumentVorlageRequired() && getDokumentVorlagen().isEmpty();
  }

  @Override
  public ExportViewResult export(FileFormat fileFormat, C context, FileType finaleKonvertierung) {
    return super.export(fileFormat, context, finaleKonvertierung == null ? getDokumentTargetFileType() : finaleKonvertierung);
  }

  @Override
  public boolean isBtnGoBackRendered() {
    return viewStackContainsOtherViewsAndShouldNotReset();
  }

  @Override
  protected void reset() {
    super.reset();

    resetDokumentVorlage();
  }
}
