package de.ivu.elect.business.stimmeingabe.entity;

import java.util.Map;
import java.util.stream.Collectors;

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.ListenkandidaturByRelativePositionComparator;
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.StimmeingabeImporterHelper;

public enum StandardStimmeingabeImporterListenkandidaturErsetzenStrategie implements StimmeingabeImporterListenkandidaturErsetzenStrategie {

  NACH_TK {
    @Override
    public Listenkandidatur findeListenkandidaturInternal(Gebiet erfassungsgebiet,
                                                          ListenkandidaturTK listenkandidaturTk,
                                                          Listenkandidatur listenkandidaturInDatei,
                                                          Map<ListenkandidaturTK, Listenkandidatur> listenkandidaturenInDbNachListenkandidaturTk,
                                                          Map<ListenkandidaturNamenUndListeTK, Listenkandidatur> listenkandidaturenInDbNachNamenUndListeTk,
                                                          Map<GruppeImGebietTK, GruppeImGebiet> gruppenImGebietInDb, StimmeingabeImporterGigContext gigInDbContext, StimmeingabeImporterHelper stimmeingabeImporterHelper) {
      return listenkandidaturenInDbNachListenkandidaturTk.get(listenkandidaturTk);
    }
  },

  NACH_NAME {
    @Override
    public Listenkandidatur findeListenkandidaturInternal(Gebiet erfassungsgebiet, ListenkandidaturTK listenkandidaturTk, Listenkandidatur listenkandidaturInDatei, Map<ListenkandidaturTK, Listenkandidatur> listenkandidaturenInDbNachListenkandidaturTk, Map<ListenkandidaturNamenUndListeTK, Listenkandidatur> listenkandidaturenInDbNachNamenUndListeTk, Map<GruppeImGebietTK, GruppeImGebiet> gruppenImGebietInDb, StimmeingabeImporterGigContext gigInDbContext, StimmeingabeImporterHelper stimmeingabeImporterHelper) {
      return listenkandidaturenInDbNachNamenUndListeTk.get(ListenkandidaturNamenUndListeTK.createFromListenkandidatur(listenkandidaturInDatei));

    }
  },

  NACH_TK_FALLBACK_NACH_NAME {
    @Override
    public Listenkandidatur findeListenkandidaturInternal(Gebiet erfassungsgebiet, ListenkandidaturTK listenkandidaturTk, Listenkandidatur listenkandidaturInDatei, Map<ListenkandidaturTK, Listenkandidatur> listenkandidaturenInDbNachListenkandidaturTk, Map<ListenkandidaturNamenUndListeTK, Listenkandidatur> listenkandidaturenInDbNachNamenUndListeTk, Map<GruppeImGebietTK, GruppeImGebiet> gruppenImGebietInDb, StimmeingabeImporterGigContext gigInDbContext, StimmeingabeImporterHelper stimmeingabeImporterHelper) {
      var result = NACH_TK
          .findeListenkandidaturInternal(erfassungsgebiet, listenkandidaturTk, listenkandidaturInDatei, listenkandidaturenInDbNachListenkandidaturTk,
              listenkandidaturenInDbNachNamenUndListeTk, gruppenImGebietInDb, gigInDbContext, stimmeingabeImporterHelper);
      if (result == null) {
        result = NACH_NAME.findeListenkandidaturInternal(erfassungsgebiet, listenkandidaturTk, listenkandidaturInDatei,
            listenkandidaturenInDbNachListenkandidaturTk,
            listenkandidaturenInDbNachNamenUndListeTk, gruppenImGebietInDb, gigInDbContext, stimmeingabeImporterHelper);
      }
      return result;
    }
  },

  NACH_GRUPPE_IM_GEBIET_POSITION_UND_LISTENKANDIDATUR_POSITION {
    @Override
    public Listenkandidatur findeListenkandidaturInternal(Gebiet erfassungsgebiet, ListenkandidaturTK listenkandidaturTk, Listenkandidatur listenkandidaturInDatei, Map<ListenkandidaturTK, Listenkandidatur> listenkandidaturenInDbNachListenkandidaturTk, Map<ListenkandidaturNamenUndListeTK, Listenkandidatur> listenkandidaturenInDbNachNamenUndListeTk, Map<GruppeImGebietTK, GruppeImGebiet> gruppenImGebietInDb, StimmeingabeImporterGigContext gigInDbContext, StimmeingabeImporterHelper stimmeingabeImporterHelper) {
      final var gruppeImGebietInDatei = listenkandidaturInDatei.getGruppeImGebiet();
      if (gruppeImGebietInDatei != null && gruppeImGebietInDatei.getVorgegebenePosition() != null && listenkandidaturInDatei.getVorgegebenePosition() != null) {
        final var gruppeImGebietInDb = StandardStimmeingabeImporterGruppeImGebietErsetzenStrategie.ERSETZE_GRUPPE_IM_GEBIET_NACH_POSITION.findGruppeImGebiet(
            gruppeImGebietInDatei, gruppenImGebietInDb, gigInDbContext, stimmeingabeImporterHelper);
        if (gruppeImGebietInDb != null) {
          var listenkandidaturenInDbSortiert = listenkandidaturenInDbNachListenkandidaturTk.values().stream()
              .filter(l -> gruppeImGebietInDb.getGruppeImGebietTK().equals(l.getGruppeImGebiet().getGruppeImGebietTK())
                  || l.getGruppe().getGruppeTK().equals(gruppeImGebietInDb.getGruppe().getGruppeTK()) && l.getGebiet()
                  .isInGebietshierarchieUebergeordnetesGebietVon(gruppeImGebietInDb.getGebiet()))
              .filter(l -> erfassungsgebiet == null || l.getListe().getGebiet().isInGebietshierarchieUebergeordnetesGebietVon(erfassungsgebiet)) // ELECT-8643
              .sorted(new ListenkandidaturByRelativePositionComparator())
              .collect(Collectors.toList());
          var listenkandidaturIndex = (int) (listenkandidaturInDatei.getVorgegebenePosition() - 1L);
          if (listenkandidaturIndex < listenkandidaturenInDbSortiert.size()) {
            return listenkandidaturenInDbSortiert.get(listenkandidaturIndex);
          }
        }
      }
      return null;
    }
  }
}
