package dev.lions.user.manager.resource;

import dev.lions.user.manager.api.UserMetricsResourceApi;
import dev.lions.user.manager.client.KeycloakAdminClient;
import dev.lions.user.manager.dto.common.UserSessionStatsDTO;
import jakarta.annotation.security.RolesAllowed;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.Path;
import lombok.extern.slf4j.Slf4j;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.representations.idm.UserRepresentation;

import java.util.List;

/**
 * Ressource REST fournissant des métriques agrégées sur les utilisateurs.
 * Implémente l'interface API commune.
 *
 * Toutes les valeurs sont calculées en temps réel à partir de Keycloak
 * (aucune approximation ni cache local).
 */
@Slf4j
@ApplicationScoped
@Path("/api/metrics/users")
public class UserMetricsResource implements UserMetricsResourceApi {

    @Inject
    KeycloakAdminClient keycloakAdminClient;

    @Override
    @RolesAllowed({ "admin", "user_manager", "auditor" })
    public UserSessionStatsDTO getUserSessionStats(String realmName) {
        String effectiveRealm = (realmName == null || realmName.isBlank()) ? "master" : realmName;
        log.info("GET /api/metrics/users/sessions - realm={}", effectiveRealm);

        try {
            RealmResource realm = keycloakAdminClient.getRealm(effectiveRealm);
            UsersResource usersResource = realm.users();

            // Liste complète des utilisateurs du realm (source de vérité Keycloak)
            List<UserRepresentation> users = usersResource.list();
            long totalUsers = users.size();

            long activeSessions = 0L;
            long onlineUsers = 0L;

            for (UserRepresentation user : users) {
                UserResource userResource = usersResource.get(user.getId());
                int sessionsForUser = userResource.getUserSessions().size();

                activeSessions += sessionsForUser;
                if (sessionsForUser > 0) {
                    onlineUsers++;
                }
            }

            return UserSessionStatsDTO.builder()
                    .realmName(effectiveRealm)
                    .totalUsers(totalUsers)
                    .activeSessions(activeSessions)
                    .onlineUsers(onlineUsers)
                    .build();
        } catch (Exception e) {
            log.error("Erreur lors du calcul des statistiques de sessions pour le realm {}", effectiveRealm, e);
            // On laisse l'exception remonter pour signaler une vraie erreur (pas de valeur approximative)
            throw new RuntimeException("Impossible de calculer les statistiques de sessions en temps réel", e);
        }
    }
}

