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

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.Nullable;
import javax.persistence.NoResultException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.gebietsbaum.entity.EntityMitGebietVeraenderbar;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.EntityMitGruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.security.entity.EntityMitSperrmerkmal;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahlausschuss.boundary.AbstractWahlausschussEntschaedigungDAO;
import de.ivu.elect.business.wahlausschuss.boundary.AbstractWahlausschussmitgliedDAO;
import de.ivu.elect.business.wahlausschuss.control.WahlausschussmitgliedDefaultComparator;
import de.ivu.elect.jee.entity.customdata.CustomData;
import de.ivu.elect.jee.faces.Messages;

public abstract class AbstractWahlausschussmitglied extends Personendaten implements WahlausschussmitgliedBase, EntityMitGruppe<PolitischeGruppe>, EntityMitGebietVeraenderbar, EntityMitSperrmerkmal {

  private static final long serialVersionUID = 1L;

  private static final Logger LOG = LoggerFactory.getLogger(AbstractWahlausschussmitglied.class);

  protected AbstractWahlausschussmitglied(CustomData customData) {
    super(customData);
  }

  protected AbstractWahlausschussmitglied() {
    super();
  }

  @Override
  public boolean hasGruppe() {
    return getGruppe() != null;
  }

  @Override
  public PolitischeGruppe getGruppe() {
    return getPolitischeGruppe();
  }

  @Override
  public void setGruppe(PolitischeGruppe politischeGruppe) {
    setPolitischeGruppe(politischeGruppe);
  }

  public static Map<Gebiet, List<Wahlausschussmitglied>> sortiereUndGruppiereNachGebiet(@Nullable Wahl wahl, AbstractWahlausschussmitgliedDAO wahlausschussmitgliedDAO) {
    if (wahl == null) {
      return new HashMap<>();
    }

    return sortiereUndGruppiereNachGebiet(wahlausschussmitgliedDAO.findByWahl(wahl));
  }

  public static Map<Gebiet, List<Wahlausschussmitglied>> sortiereUndGruppiereNachGebiet(List<Wahlausschussmitglied> wahlausschussmitglieder) {
    Collections.sort(wahlausschussmitglieder, new WahlausschussmitgliedDefaultComparator());

    Map<Gebiet, List<Wahlausschussmitglied>> result = new HashMap<>();

    for (Wahlausschussmitglied wahlausschussmitglied : wahlausschussmitglieder) {
      result.computeIfAbsent(wahlausschussmitglied.getGebiet(), key -> new ArrayList<>()).add(wahlausschussmitglied);
    }

    return result;
  }

  public boolean isVertreterVorhanden() {
    return getVertreter() != null;
  }

  public boolean isVertrittJemanden() {
    return !getWahlausschussmitgliedsByVertreter().isEmpty();
  }

  @Nullable
  public Wahlausschussmitglied getZuVertetendesWahlausschussmitglied() {
    if (isVertrittJemanden()) {
      return getWahlausschussmitgliedsByVertreter().iterator().next();
    }

    return null;
  }

  /**
   * @deprecated
   * @see PersonendatenFormatter oder erzeuge WahlausschussmitgliedFormatter
   */
  @Deprecated
  public String getFamiliennameUndVornameUndTitelUndRolleUndPolitischeGruppe(Messages messages) {
    StringBuilder result = new StringBuilder(getFamiliennameUndVornameUndTitel());

    if (result.length() > 0) {
      result.append(" ");
    }

    result.append("(");
    result.append(messages.lokalisiere(getWahlausschussrolle()));

    if (hasGruppe()) {
      result.append(", ");
      result.append(getGruppe().getKurzname());
    }

    result.append(")");

    return result.toString();
  }

  public Optional<WahlausschussEntschaedigung> getWahlausschussEntschaedigung(AbstractWahlausschussEntschaedigungDAO entschaedigungDAO) {
    try {
      return Optional.of(entschaedigungDAO.findByWahlAndRolle(getWahl(), getWahlausschussrolle()));
    } catch (NoResultException ex) { // ELECTKOM-1398
      LOG.error("ELECTKOM-1398 - KEINE WahlausschussEntschaedigung gefunden [wahl = {}, wahlausschussrolle = {}]", getWahl(), getWahlausschussrolle());
    }

    return Optional.empty();
  }
}
