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

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;

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

import javax.annotation.Nullable;

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;

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

  public AbstractWahlausschussmitglied() {
    super();
  }

  @Override
  public boolean hasGruppe() {
    return nonNull(getGruppe());
  }

  @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 abstractWahlausschussmitgliedDAO) {
    if (isNull(wahl)) {
      return new HashMap<>();
    }

    return sortiereUndGruppiereNachGebiet(abstractWahlausschussmitgliedDAO.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) {
      Gebiet gebiet = wahlausschussmitglied.getGebiet();

      if (!result.containsKey(gebiet)) {
        result.put(gebiet, new ArrayList<Wahlausschussmitglied>());
      }

      result.get(gebiet).add(wahlausschussmitglied);
    }

    return result;
  }

  public boolean isVertreterVorhanden() {
    return nonNull(getVertreter());
  }

  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(getPolitischeGruppe().getKurzname());
    }

    result.append(")");

    return result.toString();
  }

  public WahlausschussEntschaedigung getWahlausschussEntschaedigung(AbstractWahlausschussEntschaedigungDAO entschaedigungDAO) {
    return entschaedigungDAO.findByWahlAndRolle(getWahl(), getWahlausschussrolle());
  }
}
