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

import java.io.Serializable;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import de.ivu.elect.business.gebietsbaum.boundary.GebietDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.stimmzettel.control.AbstractStimmzettelKopfdatumValidator;
import de.ivu.elect.business.stimmzettel.entity.Stimmzettel;
import de.ivu.elect.business.stimmzettel.entity.StimmzettelErfassungValidationEntry;
import de.ivu.elect.business.stimmzettel.entity.StimmzettelErfassungValidationResult;
import de.ivu.elect.business.stimmzettel.entity.StimmzettelKopfdatum;
import de.ivu.elect.business.stimmzettel.entity.StimmzettelKopfdatumArt;
import de.ivu.elect.business.stimmzettel.entity.StimmzettelTeam;

@Stateless
public class StimmzettelErfassungValidator implements Serializable {
  private static final long serialVersionUID = 1L;

  @Inject
  private transient GebietDAO gebietDAO;

  @Inject
  private transient StimmzettelKopfdatumDAO stimmzettelKopfdatumDAO;

  @Inject
  private transient StimmzettelErfassung stimmzettelErfassung;

  @Inject
  private transient StimmzettelDAO stimmzettelDAO;

  public StimmzettelErfassungValidationResult validiereStimmzettelErfassung(Gebiet gebietNotAttached, StimmzettelTeam stimmzettelTeam) {

    if (gebietNotAttached == null || stimmzettelTeam == null || !stimmzettelTeam.isKopfzahlenErfassen()) {
      return new StimmzettelErfassungValidationResult(Collections.emptyMap(), Collections.emptyMap());
    }

    Gebiet gebiet = gebietDAO.attach(gebietNotAttached);

    List<StimmzettelKopfdatum> stimmzettelKopfdaten = stimmzettelKopfdatumDAO.findByGebiet(gebiet);
    List<Stimmzettel> stimmzettelList = stimmzettelDAO.findByGebiet(gebiet);
    List<Gruppe> gruppenFuerGebiet = stimmzettelErfassung.getGruppenFuerGebiet(gebietNotAttached);

    Map<StimmzettelKopfdatumArt, StimmzettelErfassungValidationEntry> validationResultOhneGruppe = new EnumMap<>(StimmzettelKopfdatumArt.class);
    Map<StimmzettelKopfdatumArt, Map<Gruppe, StimmzettelErfassungValidationEntry>> validationResultMitGruppe = new EnumMap<>(StimmzettelKopfdatumArt.class);

    for (StimmzettelKopfdatumArt art : StimmzettelKopfdatumArt.values()) {
      if (art.isKopfzahlZuErfassen(gebiet)) {
        StimmzettelErfassungValidationEntry resultOhneGruppe = StimmzettelErfassungValidationEntry.SUCCESS;
        for (AbstractStimmzettelKopfdatumValidator stimmzettelKopfdatumValidator : art.getStimmzettelKopfdatumValidators()) {
          resultOhneGruppe = resultOhneGruppe.kombiniere(stimmzettelKopfdatumValidator.validiere(art, null, stimmzettelKopfdaten, stimmzettelList));
        }
        validationResultOhneGruppe.put(art, resultOhneGruppe);
        if (art.isFuerGruppenErfassen()) {
          for (Gruppe gruppe : gruppenFuerGebiet) {
            StimmzettelErfassungValidationEntry resultMitGruppe = StimmzettelErfassungValidationEntry.SUCCESS;
            for (AbstractStimmzettelKopfdatumValidator stimmzettelKopfdatumValidator : art.getStimmzettelKopfdatumValidators()) {
              resultMitGruppe = resultMitGruppe.kombiniere(stimmzettelKopfdatumValidator.validiere(art, gruppe, stimmzettelKopfdaten, stimmzettelList));
            }
            validationResultMitGruppe.computeIfAbsent(art, x -> new HashMap<>()).put(gruppe, resultMitGruppe);
          }
        }
      }
    }

    return new StimmzettelErfassungValidationResult(validationResultOhneGruppe, validationResultMitGruppe);
  }



}
