
package de.ivu.elect.presentation.dokumente;

import static java.util.Collections.singletonList;

import java.util.List;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.DateiConstants;
import de.ivu.elect.business.datei.entity.DateiExport;
import de.ivu.elect.business.datei.entity.DateiExportPK;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.dokumente.control.ElectDokumentContext;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageConstants;
import de.ivu.elect.jee.presentation.dynamicform.AbstractEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.Property;
import de.ivu.elect.presentation.AbstractEntitySelectOneMenuProperty;
import de.ivu.elect.presentation.system.FileDownloader;

public abstract class AbstractDokumentSynchronErzeugenView<E, C extends ElectDokumentContext> extends AbstractDokumentErzeugenView<E, C> {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient ElectDokumentContextGenerator dokumentContextGenerator;

  @Inject
  private transient FileDownloader fileDownloader;

  private DokumentVorlageProperty dokumentVorlageProperty;

  private DokumentFileTypeProperty dokumentFileTypeProperty;

  public AbstractDokumentSynchronErzeugenView() {
    super();
  }

  @Nullable
  public E getSelectedEntity() {
    if (isEntitiesSelected()) {
      return getEntities().stream().findFirst().orElse(null);
    }

    return null;
  }

  public void setSelectedEntity(E entity) {
    setEntities(singletonList(entity));
  }

  public boolean isDokumentGenerated() {
    return isDownloadBereit();
  }

  @Nonnull
  public DokumentErzeugenResult erzeugeDokumentSynchron(E entity) {
    setSelectedEntity(entity);

    try {
      return erzeugeDokumentInternalSynchron(getContext());
    } catch (Exception ex) {
      onDokumentGenerierenFailed(ex);

      throw new RuntimeException(ex);
    }
  }

  public void downloadInline() {
    downloadInline(dokumentGenerierenResult);
  }

  public void downloadInline(DateiExportPK dateiExportPK) {
    downloadInline(dateiExportExtendedDAO.findByPrimaryKey(dateiExportPK));
  }
  public void downloadInline(DateiExport dateiExport) {
    fileDownloader.downloadInline(getStreamedContent(dateiExport));

    reset();
  }

  @Override
  public List<FileType> getSupportedFileTypes() {
    return singletonList(getSelectedFileType());
  }

  @Override
  protected C getContext() {
    return getContext(dokumentContextGenerator.createElectDokumentContext(), getSelectedEntity());
  }

  protected abstract C getContext(ElectDokumentContext dokumentContext, E entity);

  @Override
  public boolean isDokumentVorlagenDirektHochladenMoeglich() {
    return false;
  }

  @Override
  public boolean isBtnCancelRendered() {
    return false;
  }

  public void addDokumentProperties(FormBuilder formBuilder) {
    addDokumentProperties(formBuilder, false);
  }

  public void addDokumentProperties(FormBuilder formBuilder, boolean readonly) {
    formBuilder.addSeparator(DokumentVorlageConstants.MESSAGE_KEY_ENTITY_EINZAHL);
    formBuilder.addProperty(getDokumentVorlageProperty()).withReadonly(readonly);
    formBuilder.addProperty(getDokumentFileTypeProperty()).withReadonly(readonly);
  }

  private Property getDokumentVorlageProperty() {
    if (dokumentVorlageProperty == null) {
      dokumentVorlageProperty = new DokumentVorlageProperty();
    }

    return dokumentVorlageProperty;
  }

  private Property getDokumentFileTypeProperty() {
    if (dokumentFileTypeProperty == null) {
      dokumentFileTypeProperty = new DokumentFileTypeProperty();
    }

    return dokumentFileTypeProperty;
  }

  public class DokumentVorlageProperty extends AbstractEntitySelectOneMenuProperty<DokumentVorlage> {

    public DokumentVorlageProperty() {
      super(getDokumentVorlagen(), false);
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }

    @Override
    public DokumentVorlage getValue() {
      return getSelectedDokumentVorlage();
    }

    @Override
    public void setValue(DokumentVorlage value) {
      setSelectedDokumentVorlage(value);
    }

    @Override
    public String getItemLabel(DokumentVorlage item) {
      if (item != null) {
        return item.getName();
      }

      return "";
    }

    @Override
    protected String getMessageKeyEntityEinzahl() {
      return DokumentVorlageConstants.MESSAGE_KEY_ENTITY_EINZAHL;
    }
  }

  public class DokumentFileTypeProperty extends AbstractEnumProperty<FileType> {

    public DokumentFileTypeProperty() {
      super();
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(DateiConstants.MESSAGE_KEY_FILE_TYPE_EINZAHL);
    }

    @Override
    public FileType getValue() {
      return getSelectedFileType();
    }

    @Override
    public void setValue(FileType value) {
      setSelectedFileType(value);
    }

    @Override
    public List<FileType> getValues() {
      return getSupportedFileTypes();
    }

    @Override
    protected Class<FileType> getEnumClass() {
      return FileType.class;
    }
  }
}
