
package de.ivu.elect.was.sitzberechnung.control;

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

import java.util.HashMap;
import java.util.Map;

import de.ivu.elect.business.ergebniskonflikt.entity.ErgebnisKonfliktCustomDataFormatter;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.KandidaturStatus;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.Listenverbindung;
import de.ivu.elect.jee.faces.FacesMessageUtil;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.sitzberechnung.SitzberechnungLokalisierung;
import de.ivu.elect.was.sitzberechnung.entity.AbstractElectSitzberechnungEntity;
import de.ivu.elect.was.sitzberechnung.entity.AbstractElectSitzberechnungKandidatur;
import de.ivu.elect.was.sitzberechnung.entity.ElectSitzberechnungEntities;
import de.ivu.elect.was.sitzberechnung.entity.ElectSitzberechnungStaatenGruppe;

public class ElectSitzberechnungLokalisierung implements SitzberechnungLokalisierung {

  private final Messages messages;

  private final ErgebnisKonfliktCustomDataFormatter ergebnisKonfliktCustomDataFormatter;

  private final String wahlartName;

  private final String ergebnisartName;

  private final Map<String, Wahldurchfuehrungsgebiet> gebietPerKey;

  private final Map<String, Gruppe> gruppePerKey;

  private final Map<String, Listenverbindung> listenverbindungPerKey;

  private final Map<String, Liste> listePerKey;

  private final Map<String, Kandidatur> kandidaturPerKey;

  private final Map<String, String> minderheitengruppeBezeichnungPerKey;

  public ElectSitzberechnungLokalisierung(ElectSitzberechnungContext sitzberechnungContext, ElectSitzberechnungEntities sitzberechnungEntities) {
    super();

    Wahl wahl = sitzberechnungContext.getWahl();

    this.messages = sitzberechnungContext.getMessages();

    this.ergebnisKonfliktCustomDataFormatter = sitzberechnungContext.getErgebnisKonfliktCustomDataFormatter();

    this.wahlartName = wahl == null ? "" : wahl.getWahlart().getNameGui();

    this.ergebnisartName = this.messages.lokalisiere(sitzberechnungContext.getErgebnisart());

    this.gebietPerKey = sitzberechnungEntities.getGebiete().stream().collect(toMap(AbstractElectSitzberechnungEntity::getKey, AbstractElectSitzberechnungEntity::getEntity));
    this.gruppePerKey = sitzberechnungEntities.getGruppen().stream().collect(toMap(AbstractElectSitzberechnungEntity::getKey, AbstractElectSitzberechnungEntity::getEntity));

    this.listenverbindungPerKey = sitzberechnungEntities.getListenverbindungen().stream().collect(toMap(AbstractElectSitzberechnungEntity::getKey, AbstractElectSitzberechnungEntity::getEntity));

    this.listePerKey = sitzberechnungEntities.getListen().stream().collect(toMap(AbstractElectSitzberechnungEntity::getKey, AbstractElectSitzberechnungEntity::getEntity));

    this.kandidaturPerKey = new HashMap<>();

    for (AbstractElectSitzberechnungKandidatur< ? > kandidatur : sitzberechnungEntities.getKandidaturen()) { // Per Schleife aufgrund eines Generic-Bugs mit AbstractElectSitzberechnungKandidatur bei < JDK 11...
      this.kandidaturPerKey.put(kandidatur.getKey(), kandidatur.getEntity());
    }

    this.minderheitengruppeBezeichnungPerKey = new HashMap<>();

    for (ElectSitzberechnungStaatenGruppe staatenGruppe : sitzberechnungEntities.getStaatenGruppen()) {
      if (staatenGruppe.isMinderheitengruppe()) {
        this.minderheitengruppeBezeichnungPerKey.put(staatenGruppe.getKey(), staatenGruppe.getEntity().getBezeichnung());
      }
    }
  }

  @Override
  public String getNameDerWahlart() {
    return wahlartName;
  }

  @Override
  public String getNameDerErgebnisart() {
    return ergebnisartName;
  }

  @Override
  public String getName(Enum< ? > enumValue) {
    return messages.lokalisiere(enumValue);
  }

  @Override
  public String getName(de.ivu.elect.sitzberechnung.Gebiet gebietExtern) {
    return ergebnisKonfliktCustomDataFormatter.extractGebietDisplayName(gebietPerKey.get(gebietExtern.getKey()));
  }

  @Override
  public String getName(de.ivu.elect.sitzberechnung.Gruppe gruppeExtern) {
    return ergebnisKonfliktCustomDataFormatter.extractPolitischeGruppeDisplayName(gruppePerKey.get(gruppeExtern.getKey()));
  }

  @Override
  public String getName(de.ivu.elect.sitzberechnung.Listenverbindung listenverbindung) {
    return ergebnisKonfliktCustomDataFormatter.formatListenverbindungDisplayName(listenverbindungPerKey.get(listenverbindung.getKey()));
  }

  @Override
  public String getName(de.ivu.elect.sitzberechnung.Liste listeExtern) {
    return ergebnisKonfliktCustomDataFormatter.extractWahlvorschlagDisplayName(listePerKey.get(listeExtern.getKey()));
  }

  @Override
  public String getName(de.ivu.elect.sitzberechnung.Kandidatur kandidaturExtern) {
    return ergebnisKonfliktCustomDataFormatter.extractKandidaturDisplayName(kandidaturPerKey.get(kandidaturExtern.getKey()));
  }

  @Override
  public String getWaehlbarkeitBeschreibung(de.ivu.elect.sitzberechnung.Kandidatur kandidaturExtern) {
    Kandidatur kandidaturIntern = kandidaturPerKey.get(kandidaturExtern.getKey());

    if (kandidaturIntern == null) {
      return "";
    }

    KandidaturStatus kandidaturStatus = kandidaturIntern.getKandidaturStatus();

    if (kandidaturStatus == null) {
      return "";
    }

    String msgKey = FacesMessageUtil.getEnumMessageKey(kandidaturStatus);
    String msgKeyKurz = msgKey + ".kurz";

    if (messages.isMessageKeyVorhanden(msgKeyKurz)) {
      return messages.getMessageForMessageKey(msgKeyKurz);
    }

    return messages.getMessageForMessageKey(msgKey);
  }

  @Override
  public String getName(de.ivu.elect.sitzberechnung.Minderheitengruppe minderheitengruppe) {
    return minderheitengruppeBezeichnungPerKey.getOrDefault(minderheitengruppe.getKey(), "");
  }
}
