package dev.lions.user.manager.client.view;

import dev.lions.user.manager.client.service.AuditServiceClient;
import dev.lions.user.manager.client.service.RoleServiceClient;
import dev.lions.user.manager.client.service.UserServiceClient;
import dev.lions.user.manager.dto.user.UserSearchCriteriaDTO;
import dev.lions.user.manager.dto.user.UserSearchResultDTO;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import lombok.Data;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.logging.Logger;

/**
 * Bean JSF pour le tableau de bord
 * 
 * @author Lions User Manager
 * @version 1.0.0
 */
@Named("dashboardBean")
@ViewScoped
@Data
public class DashboardBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = Logger.getLogger(DashboardBean.class.getName());

    @Inject
    @RestClient
    private UserServiceClient userServiceClient;

    @Inject
    @RestClient
    private RoleServiceClient roleServiceClient;

    @Inject
    @RestClient
    private AuditServiceClient auditServiceClient;

    // Statistiques
    private Long totalUsers = 0L;
    private Long totalRoles = 0L;
    private Long recentActions = 0L;
    private Long activeSessions = 0L;
    private Long onlineUsers = 0L;

    // Indicateur de chargement
    private boolean loading = false;

    // Méthodes pour obtenir les valeurs formatées pour l'affichage
    public String getTotalUsersDisplay() {
        if (loading)
            return "...";
        return totalUsers != null ? String.valueOf(totalUsers) : "0";
    }

    public String getTotalRolesDisplay() {
        if (loading)
            return "...";
        return totalRoles != null ? String.valueOf(totalRoles) : "0";
    }

    public String getRecentActionsDisplay() {
        if (loading)
            return "...";
        return recentActions != null ? String.valueOf(recentActions) : "0";
    }

    public boolean isLoading() {
        return loading;
    }

    // Realm par défaut
    private String realmName = "master";

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");

    @PostConstruct
    public void init() {
        LOGGER.info("=== Initialisation du DashboardBean ===");
        LOGGER.info("Realm par défaut: " + realmName);
        LOGGER.info("UserServiceClient injecté: " + (userServiceClient != null ? "OUI" : "NON"));
        LOGGER.info("RoleServiceClient injecté: " + (roleServiceClient != null ? "OUI" : "NON"));
        LOGGER.info("AuditServiceClient injecté: " + (auditServiceClient != null ? "OUI" : "NON"));
        loadStatistics();
    }

    /**
     * Charger toutes les statistiques
     */
    public void loadStatistics() {
        loading = true;
        try {
            loadTotalUsers();
            loadTotalRoles();
            loadRecentActions();
            // Les sessions actives nécessitent une API spécifique qui n'existe pas encore
            // activeSessions = 0L;
            // onlineUsers = 0L;
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des statistiques: " + e.getMessage());
        } finally {
            loading = false;
        }
    }

    /**
     * Charger le nombre total d'utilisateurs
     */
    private void loadTotalUsers() {
        try {
            LOGGER.info("Début chargement total utilisateurs pour realm: " + realmName);
            UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
                    .realmName(realmName)
                    .page(0)
                    .pageSize(1) // On n'a besoin que du count
                    .build();

            LOGGER.info("Appel userServiceClient.searchUsers()...");
            UserSearchResultDTO result = userServiceClient.searchUsers(criteria);
            LOGGER.info("Résultat reçu: " + (result != null ? "NON NULL" : "NULL"));

            if (result != null && result.getTotalCount() != null) {
                totalUsers = result.getTotalCount();
                LOGGER.info("✅ Total utilisateurs chargé avec succès: " + totalUsers);
            } else {
                LOGGER.warning("⚠️ Résultat de recherche utilisateurs null ou totalCount null");
                if (result == null) {
                    LOGGER.warning("   - result est null");
                } else {
                    LOGGER.warning("   - result.getTotalCount() est null");
                }
                totalUsers = 0L;
            }
        } catch (Exception e) {
            LOGGER.severe("❌ ERREUR lors du chargement du nombre d'utilisateurs: " + e.getMessage());
            LOGGER.severe("   Type d'erreur: " + e.getClass().getName());
            e.printStackTrace();
            totalUsers = 0L;
            addErrorMessage("Impossible de charger le nombre d'utilisateurs: " + e.getMessage());
        }
    }

    /**
     * Charger le nombre total de rôles Realm
     */
    private void loadTotalRoles() {
        try {
            LOGGER.info("Début chargement total rôles pour realm: " + realmName);
            LOGGER.info("Appel roleServiceClient.getAllRealmRoles()...");
            List<?> roles = roleServiceClient.getAllRealmRoles(realmName);
            LOGGER.info("Résultat reçu: " + (roles != null ? "NON NULL, taille: " + roles.size() : "NULL"));

            if (roles != null) {
                totalRoles = (long) roles.size();
                LOGGER.info("✅ Total rôles chargé avec succès: " + totalRoles);
            } else {
                LOGGER.warning("⚠️ Liste de rôles null");
                totalRoles = 0L;
            }
        } catch (Exception e) {
            LOGGER.severe("❌ ERREUR lors du chargement du nombre de rôles: " + e.getMessage());
            LOGGER.severe("   Type d'erreur: " + e.getClass().getName());
            e.printStackTrace();
            totalRoles = 0L;
            addErrorMessage("Impossible de charger le nombre de rôles: " + e.getMessage());
        }
    }

    /**
     * Charger le nombre d'actions récentes (dernières 24h)
     */
    private void loadRecentActions() {
        try {
            LocalDateTime dateDebut = LocalDateTime.now().minusDays(1);
            String dateDebutStr = dateDebut.format(DATE_FORMATTER);
            String dateFinStr = LocalDateTime.now().format(DATE_FORMATTER);

            LOGGER.info("Début chargement actions récentes (24h)");
            LOGGER.info("   Date début: " + dateDebutStr);
            LOGGER.info("   Date fin: " + dateFinStr);

            // Essayer d'abord avec getSuccessCount + getFailureCount (plus efficace)
            try {
                LOGGER.info("Tentative avec getSuccessCount() et getFailureCount()...");
                dev.lions.user.manager.dto.common.CountDTO successDto = auditServiceClient.getSuccessCount(dateDebutStr,
                        dateFinStr);
                dev.lions.user.manager.dto.common.CountDTO failureDto = auditServiceClient.getFailureCount(dateDebutStr,
                        dateFinStr);

                Long successCount = (successDto != null) ? successDto.getCount() : 0L;
                Long failureCount = (failureDto != null) ? failureDto.getCount() : 0L;

                LOGGER.info("   SuccessCount: " + successCount);
                LOGGER.info("   FailureCount: " + failureCount);
                recentActions = successCount + failureCount;
                LOGGER.info("✅ Actions récentes chargées avec succès: " + recentActions);
            } catch (Exception e2) {
                LOGGER.warning("⚠️ Impossible d'obtenir les statistiques d'audit, tentative avec searchLogs: "
                        + e2.getMessage());
                // Fallback: utiliser searchLogs
                List<?> logs = auditServiceClient.searchLogs(
                        null, // acteur
                        dateDebutStr, // dateDebut
                        dateFinStr, // dateFin
                        null, // typeAction
                        null, // ressourceType
                        null, // succes
                        0, // page
                        100 // pageSize - récupérer plus de logs pour avoir un meilleur count
                );

                if (logs != null) {
                    recentActions = (long) logs.size();
                    LOGGER.info("✅ Actions récentes chargées via searchLogs: " + recentActions);
                } else {
                    LOGGER.warning("⚠️ searchLogs a retourné null");
                    recentActions = 0L;
                }
            }
        } catch (Exception e) {
            LOGGER.severe("❌ ERREUR lors du chargement des actions récentes: " + e.getMessage());
            LOGGER.severe("   Type d'erreur: " + e.getClass().getName());
            e.printStackTrace();
            recentActions = 0L;
            addErrorMessage("Impossible de charger les actions récentes: " + e.getMessage());
        }
    }

    /**
     * Rafraîchir les statistiques
     */
    public void refreshStatistics() {
        LOGGER.info("=== Rafraîchissement des statistiques ===");
        loadStatistics();
        addSuccessMessage("Statistiques rafraîchies avec succès");
    }

    // Méthodes utilitaires pour les messages
    private void addSuccessMessage(String message) {
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO, "Succès", message));
    }

    private void addErrorMessage(String message) {
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", message));
    }
}
