
package de.ivu.elect.presentation.dokumente.table;

import static java.util.Collections.emptyList;
import static java.util.Objects.nonNull;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.datei.entity.DateiImport;
import de.ivu.elect.business.dokumente.control.DokumentVorlageByImportiertAmComparator;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageConstants;
import de.ivu.elect.jee.entity.AbstractEagerLoading;
import de.ivu.elect.jee.entity.EagerLoading;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.jee.presentation.dynamictable.ColumnType;
import de.ivu.elect.presentation.dokumente.exchange.DokumentBulkExportSearchEntry;
import de.ivu.elect.presentation.table.DefaultColumnEntry;

public class AbstractDokumentBulkExportSearchEntryColumn extends DefaultColumnEntry<DokumentBulkExportSearchEntry> {

  private static final long serialVersionUID = 1L;

  public AbstractDokumentBulkExportSearchEntryColumn(String id, Messages messages, String headerKey, ColumnType type, Function<DokumentBulkExportSearchEntry, Object> getter, Object... headerParams) {
    super(id, messages, headerKey, type, getter, headerParams);
  }

  public static AbstractDokumentBulkExportSearchEntryColumn createDokumentBulkExportSearchEntryDokumentBezeichnungColumn(Messages messages) {
    return new AbstractDokumentBulkExportSearchEntryColumn("DokumentBulkExportSearchEntry-Bezeichnung", messages, "entity.einzahl.DokumentBulkExportSearchEntry.BEZEICHNUNG", ColumnType.STRING,
        DokumentBulkExportSearchEntry::getDokumentBezeichnung);
  }

  public static AbstractDokumentBulkExportSearchEntryColumn createDokumentBulkExportSearchEntryDokumentBeschreibungColumn(Messages messages) {
    return new AbstractDokumentBulkExportSearchEntryColumn("DokumentBulkExportSearchEntry-Beschreibung", messages, "entity.einzahl.DokumentBulkExportSearchEntry.BESCHREIBUNG", ColumnType.STRING,
        DokumentBulkExportSearchEntry::getDokumentBeschreibung);
  }

  public static AbstractDokumentBulkExportSearchEntryColumn createDokumentBulkExportSearchEntryFileTypeColumn(Messages messages) {
    return new AbstractDokumentBulkExportSearchEntryColumn("DokumentBulkExportSearchEntry-FileType", messages, "dokument.erzeugen.zieldatei.typ", ColumnType.ENUM,
        DokumentBulkExportSearchEntry::getFileType);
  }

  public static AbstractDokumentBulkExportSearchEntryColumn createDokumentBulkExportSearchEntryDokumentVorlageNameColumn(Messages messages) {
    return new DokumentBulkExportSearchEntryDokumentVorlageNameColumn(messages);
  }

  public static AbstractDokumentBulkExportSearchEntryColumn createDokumentBulkExportSearchEntryDokumentVorlageBeschreibungColumn(Messages messages) {
    return new AbstractDokumentBulkExportSearchEntryColumn("DokumentBulkExportSearchEntry-DokumentVorlage-Beschreibung", messages, DokumentVorlageConstants.MESSAGE_KEY_BESCHREIBUNG_EINZAHL,
        ColumnType.COLLECTION, dokumentBulkExportSearchEntry -> {
          List<String> result = new ArrayList<>();

          if (nonNull(dokumentBulkExportSearchEntry)) {
            result.addAll(dokumentBulkExportSearchEntry.getDokumentVorlagenRequiredBeschreibungen());
          }

          return result.stream() //
              .filter(StringUtils::isNotBlank) //
              .collect(toList());
        });
  }

  public static AbstractDokumentBulkExportSearchEntryColumn createDokumentBulkExportSearchEntryDokumentVorlageAktualisiertAmColumn(Messages messages) {
    return new AbstractDokumentBulkExportSearchEntryColumn("DokumentBulkExportSearchEntry-DokumentVorlage-ImportiertAm", messages,
        "entity.einzahl.DokumentBulkExportSearchEntry.DOKUMENT_VORLAGE.AKTUALISIERT_AM", ColumnType.TIMESTAMP, dokumentBulkExportSearchEntry -> {
          if (nonNull(dokumentBulkExportSearchEntry)) {
            List<DokumentVorlage> dokumentVorlagen = new ArrayList<>(dokumentBulkExportSearchEntry.getDokumentVorlagen());

            if (!dokumentVorlagen.isEmpty()) {
              dokumentVorlagen.sort(DokumentVorlageByImportiertAmComparator.DESCENDING);

              DokumentVorlage dokumentVorlage = dokumentVorlagen.get(0);

              if (nonNull(dokumentVorlage) && nonNull(dokumentVorlage.getDateiImport())) {
                return dokumentVorlage.getDateiImport().getImportiertAm();
              }
            }
          }

          return null;
        });
  }

  public static class DokumentBulkExportSearchEntryDokumentVorlageNameColumn extends AbstractDokumentBulkExportSearchEntryColumn {

    private static final long serialVersionUID = 1L;

    private final AbstractDokumentBulkExportSearchEntryColumn dokumentBulkExportSearchEntryDokumentVorlageBeschreibungColumn;

    public DokumentBulkExportSearchEntryDokumentVorlageNameColumn(Messages messages) {
      super("DokumentBulkExportSearchEntry-DokumentVorlage-Name", messages, DokumentVorlageConstants.MESSAGE_KEY_ENTITY_EINZAHL, ColumnType.COLLECTION, dokumentBulkExportSearchEntry -> {
        if (nonNull(dokumentBulkExportSearchEntry)) {
          if (dokumentBulkExportSearchEntry.isDokumentVorlageRequired() && !dokumentBulkExportSearchEntry.isDokumentVorlagenConfigured()) {
            return messages.getMessageForMessageKey("dokument.bulk.export.search.dokument.vorlage.missing", dokumentBulkExportSearchEntry.getDokumentVorlagenRequiredAnzahl());
          }

          return dokumentBulkExportSearchEntry.getDokumentVorlagen().stream() //
              .filter(dokumentVorlage -> nonNull(dokumentVorlage)) //
              .map(DokumentVorlage::getName) //
              .collect(toList());
        }

        return emptyList();
      });

      this.dokumentBulkExportSearchEntryDokumentVorlageBeschreibungColumn = AbstractDokumentBulkExportSearchEntryColumn.createDokumentBulkExportSearchEntryDokumentVorlageBeschreibungColumn(messages);
    }

    @Override
    public String getTooltip(DokumentBulkExportSearchEntry dokumentBulkExportSearchEntry) {
      List<Object> result = new ArrayList<>();

      Object displayValue = dokumentBulkExportSearchEntryDokumentVorlageBeschreibungColumn.getDisplayValue(dokumentBulkExportSearchEntry);

      if (nonNull(displayValue)) {
        if (displayValue instanceof Collection< ? >) {
          result.addAll((Collection< ? >) displayValue);
        } else {
          result.add(displayValue);
        }
      }

      return result.stream() //
          .map(String::valueOf) //
          .collect(joining(TOOLTIP_LINE_SEPARATOR + TOOLTIP_LINE_SEPARATOR));
    }
  }

  @Override
  public EagerLoading<DokumentBulkExportSearchEntry> getEagerLoading() {
    EagerLoading<DokumentBulkExportSearchEntry> defaultEagerLoading = super.getEagerLoading();

    return new AbstractEagerLoading<DokumentBulkExportSearchEntry>() {

      @Override
      public DokumentBulkExportSearchEntry eagerLoad(DokumentBulkExportSearchEntry dokumentBulkExportSearchEntry) {
        if (nonNull(defaultEagerLoading)) {
          defaultEagerLoading.eagerLoad(dokumentBulkExportSearchEntry);
        }

        for (DokumentVorlage dokumentVorlage : dokumentBulkExportSearchEntry.getDokumentVorlagen()) {
          DateiImport dateiImport = dokumentVorlage.getDateiImport();

          if (nonNull(dateiImport)) {
            dateiImport.getImportiertAm(); // ELECT-7241
          }
        }

        return dokumentBulkExportSearchEntry;
      }
    };
  }
}
