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

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

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

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppeimgebiet.boundary.GruppeImGebietDAO;
import de.ivu.elect.business.gruppeimgebiet.boundary.GruppeImGebietHierarchyBuilder;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.wahl.entity.Wahl;

@Stateless
@Specializes
public class CoreGebietUebernehmen extends GebietUebernehmen {

  private static final String GRUPPE_IM_GEBIET_DER_WAHL_NACH_TK = "GRUPPE_IM_GEBIET_DER_WAHL_NACH_TK";

  @Inject
  private transient GruppeImGebietHierarchyBuilder gruppeImGebietHierarchyBuilder;

  @Inject
  private transient GruppeImGebietDAO gruppeImGebietDAO;

  @Override
  protected void postCreateGebiet(Map<String, Object> postCreateContext, Gebiet neueZielGebiet, boolean wurzelgebietAngelegt) {
    super.postCreateGebiet(postCreateContext, neueZielGebiet, wurzelgebietAngelegt);
    if (wurzelgebietAngelegt || neueZielGebiet.getUebergeordnetesGebiet() == null) {
      return; // es kann noch keine Wahlvorschläge geben => gruppeImGebiet muss nicht aktualisiert werden
    }

    Map<Gebiet, Set<GruppeImGebiet>> gigsNachGebiet = (Map<Gebiet, Set<GruppeImGebiet>>) postCreateContext.get(GRUPPE_IM_GEBIET_DER_WAHL_NACH_TK);
    Set<GruppeImGebiet> uebergeordneteGigs = gigsNachGebiet.get(neueZielGebiet.getUebergeordnetesGebiet());
    gigsNachGebiet.put(neueZielGebiet, gruppeImGebietHierarchyBuilder.createGruppenImGebietAusGruppenImGebietUebergeordnet(neueZielGebiet, uebergeordneteGigs));
  }

  @Override
  protected Map<String, Object> createPostCreateContext(Wahl zielWahl) {
    Map<String, Object> postCreateContext = super.createPostCreateContext(zielWahl);
    postCreateContext.put(GRUPPE_IM_GEBIET_DER_WAHL_NACH_TK, getGigNachGebiet(zielWahl));
    return postCreateContext;
  }

  private Map<Gebiet, Set<GruppeImGebiet>> getGigNachGebiet(Wahl zielWahl) {
    return gruppeImGebietDAO.findByWahl(zielWahl).stream()
        .collect(Collectors.groupingBy(GruppeImGebiet::getGebiet, Collectors.toSet()));
  }
}
