
package de.ivu.elect.was.exchange.stimmeingabe;

import static java.util.Arrays.asList;

import java.util.List;
import java.util.Map;

import javax.enterprise.inject.Specializes;
import javax.inject.Inject;

import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebietTK;
import de.ivu.elect.business.kandidatur.control.ListenkandidaturNamenUndListeTK;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.kandidatur.entity.ListenkandidaturTK;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeImportContext;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeImporterHelper;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.stimmeingabe.entity.StandardStimmeingabeImporterGruppeImGebietErsetzenStrategie;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeImporterErsetzenStrategie;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeImporterGigContext;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeImporterGruppeImGebietErsetzenStrategie;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeImporterListenkandidaturErsetzenStrategie;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeImporterReferendumOptionErsetzenStrategie;
import de.ivu.elect.exchange.ImportMapper;

@Specializes
public class NlStimmeingabeImportExchange extends DefaultStimmeingabeImportExchange {

  @Inject
  private transient Eml510aBackupRestoreImportMapper eml510aBackupRestoreImportMapper;

  @Inject
  private transient Eml510StimmeingabeImportMapper eml510StimmeingabeImportMapper;

  @Inject
  private transient Eml510StimmeingabeZipImportMapper eml510StimmeingabeZipImportMapper;

  public NlStimmeingabeImportExchange() {
    super();
  }

  @Override
  protected Iterable< ? extends ImportMapper<List<Ergebniseingang>, StimmeingabeImportContext>> getAllSupportedMapper() {
    return asList( //
        eml510aBackupRestoreImportMapper, //

        eml510StimmeingabeImportMapper, //
        eml510StimmeingabeZipImportMapper //
    );
  }

  @Override
  public StimmeingabeImporterErsetzenStrategie getStimmeingabeImporterErsetzenStrategie(FileFormat fileFormat, StimmeingabeImportContext context) {
    return new NlStimmeingabeImporterErsetzenStrategie();
  }

  private static class NlStimmeingabeImporterErsetzenStrategie implements StimmeingabeImporterErsetzenStrategie {

    @Override
    public StimmeingabeImporterGruppeImGebietErsetzenStrategie getStimmeingabeImporterGruppeImGebietErsetzenStrategie() {
      return StandardStimmeingabeImporterGruppeImGebietErsetzenStrategie.ERSETZE_GRUPPE_IM_GEBIET_NACH_TK_FALLBACK_POSITION;
    }

    @Override
    public StimmeingabeImporterListenkandidaturErsetzenStrategie getStimmeingabeImporterListenkandidaturErsetzenStrategie() {
      return new NlStimmeingabeImporterListenkandidaturErsetzenStrategie();
    }

    @Override
    public StimmeingabeImporterReferendumOptionErsetzenStrategie getStimmeingabeImporterReferendumOptionErsetzenStrategie() {
      return StimmeingabeImporterErsetzenStrategie.DEFAULT.getStimmeingabeImporterReferendumOptionErsetzenStrategie();
    }

    private static class NlStimmeingabeImporterListenkandidaturErsetzenStrategie implements StimmeingabeImporterListenkandidaturErsetzenStrategie {

      @Override
      public Listenkandidatur findeListenkandidatur(Gebiet erfassungsgebiet, ListenkandidaturTK listenkandidaturTk, Listenkandidatur listenkandidaturInDatei,
          Map<ListenkandidaturTK, Listenkandidatur> listenkandidaturenInDbNachListenkandidaturTk, Map<ListenkandidaturNamenUndListeTK, Listenkandidatur> listenkandidaturenInDbNachNamenUndListeTk,
          Map<GruppeImGebietTK, GruppeImGebiet> gruppenImGebietInDb, StimmeingabeImporterGigContext gigInDbContext, StimmeingabeImporterHelper stimmeingabeImporterHelper) {
        return listenkandidaturenInDbNachListenkandidaturTk.values().stream() //
            .filter(listenkandidaturInDb -> listenkandidaturInDb.getRelativePosition().equals(listenkandidaturInDatei.getRelativePosition())) //
            .filter(listenkandidaturInDb -> listenkandidaturInDb.getGruppe().getSchluessel().equalsIgnoreCase(listenkandidaturInDatei.getGruppe().getSchluessel())) //
            .filter(listenkandidaturInDb -> listenkandidaturInDb.getGebiet().isInGebietshierarchieUebergeordnetesGebietVon(erfassungsgebiet)) //
            .findFirst().orElse(null);
      }
    }
  }
}
