
package de.ivu.elect.business.entschaedigung.boundary;

import static java.util.stream.Collectors.toSet;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.ejb.Stateless;
import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.DateiExport;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.dokumente.boundary.AbstractDokumentGenerator;
import de.ivu.elect.business.dokumente.control.ProgressMonitor;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.entschaedigung.control.AuszahlungDocumentContext;
import de.ivu.elect.business.entschaedigung.entity.Auszahlung;
import de.ivu.elect.business.entschaedigung.entity.AuszahlungCalculated;
import de.ivu.elect.business.entschaedigung.entity.Entschaedigung;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;

@Stateless
public class AuszahlungDocumentGenerator extends AbstractDokumentGenerator<Auszahlung, AuszahlungDocumentContext> {

  @Inject
  private transient AuszahlungDAO auszahlungDao;

  @Inject
  private transient EntschaedigungDAO entschaedigungDao;

  public AuszahlungDocumentGenerator() {
    super();
  }

  @Override
  public DokumentVorlageArt getDokumentVorlageArt() {
    return DokumentVorlageArt.AUSZAHLUNG;
  }

  @Override
  protected void postGeneriereDokument(DateiExport dateiExport, List<Auszahlung> auszahlungen, DokumentVorlage dokumentVorlage, FileType zieldateiTyp, Wahl wahlNotAttached,
      Wahltermin wahlterminNotAttached, AuszahlungDocumentContext context, ProgressMonitor monitor) {
    super.postGeneriereDokument(dateiExport, auszahlungen, dokumentVorlage, zieldateiTyp, wahlNotAttached, wahlterminNotAttached, context, monitor);

    protokollierePersonendatenDateiExport(attachPersonendaten(auszahlungen), dateiExport, dokumentVorlage, context.getBenutzer());
  }

  private Set< ? extends Personendaten> attachPersonendaten(Collection<Auszahlung> auszahlungen) {
    return auszahlungen.stream() //
        .flatMap(auszahlung -> auszahlung.getEntschaedigungen(entschaedigungDao).stream()) //
        .map(Entschaedigung::getPersonendaten) //
        .collect(toSet());
  }

  @Override
  protected Auszahlung attach(Auszahlung auszahlung, AuszahlungDocumentContext context) {
    AuszahlungCalculated auszahlungCalculated = new AuszahlungCalculated(attach(auszahlung), attach(context.getAuszahlungCalculated().getEntschaedigungen()));
    context.setAuszahlungCalculated(auszahlungCalculated);

    return auszahlungCalculated.getAuszahlung();
  }

  private Auszahlung attach(Auszahlung auszahlung) {
    return auszahlungDao.attach(auszahlung);
  }

  private List<Entschaedigung> attach(List<Entschaedigung> entschaedigungen) {
    return entschaedigungDao.attachAll(entschaedigungen);
  }
}
