
package de.ivu.elect.presentation.exchange;

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

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

import de.ivu.elect.business.benutzerverwaltung.entity.Benutzer;
import de.ivu.elect.business.datei.entity.DateiImport;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.exchange.control.AbstractImporterExporter;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.gebietsbaum.boundary.GebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.security.control.ElectCommonPrincipal;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelector;
import de.ivu.elect.business.wahl.boundary.WahlterminSessionSelect;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.jee.faces.FacesMessageUtil;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.faces.UserTimeZone;
import de.ivu.elect.jee.presentation.security.StartViewResolver;
import de.ivu.elect.jee.presentation.view.AbstractView;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;
import de.ivu.elect.presentation.mandant.MandantSessionSelect;


import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;

public abstract class AbstractImportExportView<Context> extends AbstractView {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient ElectCommonPrincipal principal;

  @Inject
  private transient UserTimeZone userTimeZone;

  @Inject
  private transient FileFormatViewSelect fileFormatViewSelect;

  @Inject
  private transient StartViewResolver startViewResolver;

  @Inject
  protected transient WahlterminSessionSelect wahlterminSelect;

  @Inject
  protected transient WahlSessionSelector wahlSelect;

  @Inject
  protected transient GebietSessionSelect gebietSelect;

  @Inject
  protected transient MandantSessionSelect mandantSessionSelect;

  @Inject
  protected transient GebietNummerFormatter gebietNummerFormatter;

  public AbstractImportExportView() {
    super();
  }

  @PostConstruct
  public void initFileFormat() {
    // ELECT-7622
    //    try {
    //      if (!isFileFormatSelected()) {
    //        List<FileFormat> supportedFileFormats = getSupportedFileFormatsUnsorted();
    //
    //        if (supportedFileFormats.size() == 1) {
    //          setSelectedFileFormat(supportedFileFormats.get(0));
    //        }
    //      }
    //    } catch (Exception ex) {
    //      LOG.warn("Fehler beim Ermitteln des FileFormat: " + ex.getMessage() + ", " + this.getClass());
    //    }
  }

  @Nullable
  @PreConditionCheck
  public String checkPreCondition() {
    if (getExchangeDescription().isSpecificPerWahlOrWahltermin() && !(isWahlSelected() || isWahlterminSelected())) {
      return getStartViewId();
    }

    return null;
  }

  public boolean isPageMenuRendered() {
    return getExchangeDescription().isPageMenuRendered();
  }

  protected abstract ExchangeDescription getExchangeDescription();

  public List<FileType> getSupportedFileTypes() {
    return getSupportedFileFormats().stream() //
        .map(FileFormat::getFileType) //
        .distinct() //
        .collect(toList());
  }

  public boolean isSupportedFileFormatsRendered() {
    return true;
  }

  public List<FileFormat> getSupportedFileFormats() {
    List<FileFormat> result = new ArrayList<>(getSupportedFileFormatsUnsorted());
    result.sort(new FileFormatByMessageAndTypeComparator(userLocale.getLocale(), messages, getKnownFileType()));

    return result;
  }

  @Nullable
  protected FileType getKnownFileType() {
    return null;
  }

  public List<FileFormat> getSupportedFileFormatsUnsorted() {
    if (!principal.hasUseCasePermission(getExchangeDescription().getUseCasePermission())) {
      return emptyList(); // ELECT-12336
    }
    if (!getExchangeDescription().isSpecificPerWahlOrWahltermin() || isWahlSelected() || isWahlterminSelected()) {
      return getImporterExporter().getSupportedFileFormats(getContext());
    }

    return emptyList();
  }

  public List<FileFormat> getSupportedFileFormats(FileFormat fileFormat) {
    if (fileFormat != null) {
      FileType fileType = fileFormat.getFileType();

      return getSupportedFileFormats().stream() //
          .filter(supportedFileFormat -> supportedFileFormat.getFileType().equals(fileType)) //
          .collect(toList());
    }

    return new ArrayList<>();
  }

  protected String getStartViewId() {
    return startViewResolver.getStartViewId();
  }

  protected abstract AbstractImporterExporter<Context> getImporterExporter();

  protected abstract Context getContext();

  protected boolean isFileFormatSelected() {
    return fileFormatViewSelect.isSelected();
  }

  // ELECT-2462 NICHT im XHTML verwenden, sonst kann es im JBoss 7.1.3 knallen! --> getFileFormatSelect()
  @Nullable
  public FileFormat getSelectedFileFormat() {
    return fileFormatViewSelect.getSelectedFileFormat();
  }

  // ELECT-2462 NICHT im XHTML verwenden, sonst kann es im JBoss 7.1.3 knallen! --> getFileFormatSelect()
  public void setSelectedFileFormat(FileFormat selectedFileFormat) {
    fileFormatViewSelect.setSelectedFileFormat(selectedFileFormat);
  }

  public FileFormatViewSelect getFileFormatSelect() {
    return fileFormatViewSelect;
  }

  protected boolean isWahlSelected() {
    return wahlSelect.isSelected();
  }

  protected Wahl getSelectedWahl() {
    return wahlSelect.getEntity();
  }

  protected boolean isWahlterminSelected() {
    return wahlterminSelect.isSelected();
  }

  protected Wahltermin getSelectedWahltermin() {
    return wahlterminSelect.getEntity();
  }

  protected boolean isGebietSelected() {
    return gebietSelect.isSelected();
  }

  protected Gebiet getSelectedGebiet() {
    return gebietSelect.getEntity();
  }

  protected String getSelectedGebietNameFormatted() {
    return formatGebietName(getSelectedGebiet());
  }

  protected String formatGebietName(Gebiet gebiet) {
    return gebietNummerFormatter.getDarstellung(gebiet);
  }

  public boolean isNonCsvAndOnlyOneFormat(DateiImport dateiImport) {
    return !isCsvDatei(dateiImport) && isSingleSupportedFileFormat(dateiImport);
  }

  protected boolean isCsvDatei(DateiImport dateiImport) {
    return dateiImport != null && dateiImport.getDatei() != null && dateiImport.getDatei().isCsvDatei();
  }

  protected boolean isSingleSupportedFileFormat(DateiImport dateiImport) {
    return dateiImport != null && dateiImport.getDatei() != null && getSupportedFileFormats(dateiImport.getDatei().getFileFormat()).size() == 1;
  }

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

  public boolean isBtnGoBackDisabled() {
    return false;
  }

  protected ElectCommonPrincipal getPrincipal() {
    return principal;
  }

  protected Benutzer getBenutzer() {
    return getPrincipal().getLogin();
  }

  protected String getEnumMsgKey(Enum< ? > enumValue) {
    return FacesMessageUtil.getEnumMessageKey(enumValue);
  }

  protected Mandant getMandant() {
    return mandantSessionSelect.getMandant();
  }

  protected UserTimeZone getUserTimeZone() {
    return userTimeZone;
  }
}
