package de.ivu.elect.presentation.benutzerverwaltung.table;

import de.ivu.elect.business.benutzerverwaltung.boundary.AbstractBenutzerDAO;
import de.ivu.elect.business.benutzerverwaltung.entity.Benutzer;
import de.ivu.elect.business.benutzerverwaltung.entity.Rolle;
import de.ivu.elect.business.benutzerverwaltung.entity.RolleArt;
import de.ivu.elect.business.benutzerverwaltung.entity.RolleConstants;
import de.ivu.elect.jee.faces.FacesMessageUtil;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.jee.presentation.dynamictable.ColumnType;


import java.util.*;
import java.util.function.Function;

public class BenutzerRollenColumn extends AbstractBenutzerColumn<Benutzer> {

  public BenutzerRollenColumn(Messages messages, AbstractBenutzerDAO abstractBenutzerDAO) {
    super("Benutzer-Rollen", messages, RolleConstants.MESSAGE_KEY_ENTITY_MEHRZAHL, ColumnType.COLLECTION,
        getGetter(messages, abstractBenutzerDAO));
  }

  private static Function<Benutzer, Object> getGetter(Messages messages, AbstractBenutzerDAO abstractBenutzerDAO) {
    return benutzer -> {
      Map<RolleArt, List<String>> rollenProRolleArt = getRollenProRolleArtMap(abstractBenutzerDAO, benutzer);

      boolean showRolleArtName = rollenProRolleArt.values().stream().filter(strings -> !strings.isEmpty()).count() > 1;

      List<String> result = new ArrayList<>();
      for (RolleArt rolleArt : RolleArt.values()) {
        List<String> rollen = rollenProRolleArt.get(rolleArt);
        if (!rollen.isEmpty()) {
          if (!result.isEmpty()) {
            result.add("\u00A0"); // Leerzeile zur optischen Trennung der Rollenarten
          }
          if (showRolleArtName && !rolleArt.isFachlich()) {
            result.add(messages.getMessageForMessageKey(FacesMessageUtil.getEnumMessageKey(rolleArt) + ".MEHRZAHL") + ":");
          }
          rollen.sort(String::compareTo);
          result.addAll(rollen);
        }
      }
      return result;
    };
  }

  private static Map<RolleArt, List<String>> getRollenProRolleArtMap(AbstractBenutzerDAO abstractBenutzerDAO, Benutzer benutzer) {
    Map<RolleArt, List<String>> rollenProRolleArt = new LinkedHashMap<>();
    for (RolleArt rolleArt : RolleArt.values()) {
      rollenProRolleArt.put(rolleArt, new ArrayList<>());
    }
    for (Rolle rolle : abstractBenutzerDAO.attach(benutzer).getRolles()) {
      rollenProRolleArt.get(rolle.getRolleArt()).add(rolle.getName());
    }
    return rollenProRolleArt;
  }
}
