
package de.ivu.elect.wus.exchange.gruppe;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.WusFeaturesAktiviert;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.gruppe.boundary.GruppeFactory;
import de.ivu.elect.business.gruppe.boundary.PolitischeGruppeDAO;
import de.ivu.elect.business.gruppe.boundary.PolitischeGruppeFactory;
import de.ivu.elect.business.gruppe.control.GruppeExchangeContext;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.image.entity.Bild;

public abstract class AbstractDefaultGruppeMapper<T extends ExchangeGruppeDTO>
    implements
    GruppeImportMapper,
    GruppeExportMapper {

  public static final String FILE_FORMAT_NAME = "file.format.gruppe.default";

  @Inject
  private GruppeFactory gruppeFactory;

  @Inject
  private PolitischeGruppeFactory politischeGruppeFactory;

  @Inject
  private PolitischeGruppeDAO politischeGruppeDAO;

  @Inject
  private transient WusFeaturesAktiviert wusFeaturesAktiviert;

  protected abstract T createEntity();

  protected T mappeEntity(de.ivu.elect.business.gruppe.entity.Gruppe from) {
    T to = createEntity();
    to.setFarbeExtern(from.getFarbeExtern());
    to.setFarbe(from.getFarbe());
    to.setName(from.getName());
    to.setGruppeArt(from.getGruppeArt());
    to.setKurzname(from.getKurzname());
    to.setZusatzbezeichnung(from.getZusatzbezeichnung());
    to.setSchluessel(from.getSchluessel());
    if (from instanceof PolitischeGruppe) {
      PolitischeGruppe politischeGruppe = politischeGruppeDAO.findByPrimaryKey(from.getPk());
      to.setInPraesentation(politischeGruppe.getInPraesentation());
      to.setMinderheit(politischeGruppe.getMinderheit());
    }
    if (from.getLogo() != null) {
      to.setLogoContent(from.getLogo().getContentBase64());
      to.setLogoMimeType(from.getLogo().getMimeType());
    }
    to.setRelativePosition(from.getRelativePosition());
    to.setVorgegebenePosition(from.getVorgegebenePosition());

    return to;
  }

  protected List<Gruppe> mappeEntityExternToIntern(List<T> entityListe) {
    return entityListe.stream().map(this::mappeEntity).collect(Collectors.toCollection(() -> new ArrayList<>(entityListe.size())));
  }

  protected de.ivu.elect.business.gruppe.entity.Gruppe mappeEntity(T from) {
    if (isPolitischeGruppe(from)) {
      PolitischeGruppe to = politischeGruppeFactory.create();
      mappeGruppe(to, from);
      to.setInPraesentation(from.getInPraesentation());
      to.setMinderheit(from.getMinderheit());
      return to;
    } else {
      de.ivu.elect.business.gruppe.entity.Gruppe to = gruppeFactory.create();
      mappeGruppe(to, from);
      return to;
    }
  }

  private void mappeGruppe(Gruppe to, T from) {
    to.setFarbeExtern(from.getFarbeExtern());
    to.setFarbe(from.getFarbe());
    to.setName(from.getName());
    to.setGruppeArt(from.getGruppeArt());
    to.setKurzname(from.getKurzname());
    to.setZusatzbezeichnung(from.getZusatzbezeichnung());
    to.setSchluessel(from.getSchluessel());
    if (StringUtils.isNotBlank(from.getLogoContent())) {
      Bild logo = new Bild();
      logo.setMimeType(from.getLogoMimeType());
      logo.setContentBase64(from.getLogoContent());
      to.setLogo(logo);
    }
    to.setVorgegebenePosition(from.getVorgegebenePosition());
    to.setRelativePosition(from.getRelativePosition());
  }

  private boolean isPolitischeGruppe(T from) {
    return from.getGruppeArt()!=null && from.getGruppeArt().isPolitischeGruppe();
  }

  @Override
  public boolean isAcceptContext(GruppeExchangeContext context) {
    return wusFeaturesAktiviert.isWusOderWusWasZusammen() && context.getWahl() != null;
  }

  @Override
  public FileFormat getFileFormat() {
    return new FileFormat(FILE_FORMAT_NAME, getFileType());
  }

  protected abstract FileType getFileType();
}
