package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.NotificationService;
import dev.lions.unionflow.server.api.dto.notification.request.*;
import dev.lions.unionflow.server.api.dto.notification.response.*;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import jakarta.inject.Inject;
import jakarta.annotation.PostConstruct;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.logging.Logger;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.RetryService;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Bean JSF pour la gestion des notifications
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@Named("notificationBean")
@ViewScoped
public class NotificationBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(NotificationBean.class);
    
    @Inject
    @RestClient
    private NotificationService notificationService;
    
    @Inject
    private UserSession userSession;
    
    @Inject
    ErrorHandlerService errorHandler;
    
    @Inject
    RetryService retryService;
    
    // Données
    private List<NotificationResponse> notifications = new ArrayList<>();
    private List<NotificationResponse> notificationsNonLues = new ArrayList<>();
    private List<NotificationResponse> notificationsEnAttente = new ArrayList<>();
    private List<TemplateNotificationResponse> templates = new ArrayList<>();

    // Sélections
    private NotificationResponse notificationSelectionnee;
    private TemplateNotificationResponse templateSelectionne;

    // Filtres
    private String filtreType = "toutes"; // toutes, non-lues, en-attente

    // Nouveaux éléments
    private CreateNotificationRequest nouvelleNotification = CreateNotificationRequest.builder().build();
    private CreateTemplateNotificationRequest nouveauTemplate = CreateTemplateNotificationRequest.builder().build();
    private NotificationService.NotificationGroupeeRequest notificationGroupee = new NotificationService.NotificationGroupeeRequest();
    
    @PostConstruct
    public void init() {
        chargerNotifications();
        chargerNotificationsNonLues();
        chargerNotificationsEnAttente();
    }
    
    public void chargerNotifications() {
        try {
            if (userSession != null && userSession.getCurrentUser() != null && userSession.getCurrentUser().getId() != null) {
                notifications = retryService.executeWithRetrySupplier(
                    () -> notificationService.listerNotificationsParMembre(userSession.getCurrentUser().getId()),
                    "chargement des notifications"
                );
            } else {
                notifications = new ArrayList<>();
            }
            LOG.infof("Notifications chargées: %d", notifications.size());
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des notifications");
            errorHandler.handleException(e, "lors du chargement des notifications", null);
            notifications = new ArrayList<>();
        }
    }
    
    public void chargerNotificationsNonLues() {
        try {
            if (userSession != null && userSession.getCurrentUser() != null && userSession.getCurrentUser().getId() != null) {
                notificationsNonLues = retryService.executeWithRetrySupplier(
                    () -> notificationService.listerNotificationsNonLuesParMembre(userSession.getCurrentUser().getId()),
                    "chargement des notifications non lues"
                );
            } else {
                notificationsNonLues = new ArrayList<>();
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des notifications non lues");
            notificationsNonLues = new ArrayList<>();
        }
    }
    
    public void chargerNotificationsEnAttente() {
        try {
            notificationsEnAttente = retryService.executeWithRetrySupplier(
                () -> notificationService.listerNotificationsEnAttenteEnvoi(),
                "chargement des notifications en attente"
            );
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des notifications en attente");
            notificationsEnAttente = new ArrayList<>();
        }
    }
    
    public void marquerCommeLue() {
        if (notificationSelectionnee == null || notificationSelectionnee.getId() == null) {
            errorHandler.showWarning("Attention", "Aucune notification sélectionnée");
            return;
        }
        
        try {
            retryService.executeWithRetrySupplier(
                () -> {
                    notificationService.marquerCommeLue(notificationSelectionnee.getId());
                    return null;
                },
                "marquage d'une notification comme lue"
            );
            
            // Recharger les données depuis le backend
            chargerNotifications();
            chargerNotificationsNonLues();
            chargerNotificationsEnAttente();
            
            LOG.infof("Notification marquée comme lue: %s", notificationSelectionnee.getId());
            errorHandler.showSuccess("Succès", "Notification marquée comme lue");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du marquage de la notification");
            errorHandler.handleException(e, "lors du marquage d'une notification", null);
        }
    }
    
    public void creerNotification() {
        try {
            NotificationResponse notificationCreee = retryService.executeWithRetrySupplier(
                () -> notificationService.creerNotification(nouvelleNotification),
                "création d'une notification"
            );

            // Recharger les données depuis le backend
            chargerNotifications();
            chargerNotificationsNonLues();
            chargerNotificationsEnAttente();

            // Réinitialiser le formulaire
            nouvelleNotification = CreateNotificationRequest.builder().build();

            LOG.infof("Notification créée: %s", notificationCreee.getId());
            errorHandler.showSuccess("Succès", "Notification créée avec succès");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la création de la notification");
            errorHandler.handleException(e, "lors de la création d'une notification", null);
        }
    }
    
    public void envoyerNotificationsGroupees() {
        try {
            retryService.executeWithRetrySupplier(
                () -> {
                    notificationService.envoyerNotificationsGroupees(notificationGroupee);
                    return null;
                },
                "envoi de notifications groupées"
            );
            notificationGroupee = new NotificationService.NotificationGroupeeRequest();
            errorHandler.showSuccess("Succès", "Notifications groupées envoyées avec succès");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de l'envoi des notifications groupées");
            errorHandler.handleException(e, "lors de l'envoi de notifications groupées", null);
        }
    }
    
    public List<NotificationResponse> getNotificationsFiltrees() {
        switch (filtreType) {
            case "non-lues":
                return notificationsNonLues;
            case "en-attente":
                return notificationsEnAttente;
            default:
                return notifications;
        }
    }

    // Getters et Setters
    public List<NotificationResponse> getNotifications() { return notifications; }
    public void setNotifications(List<NotificationResponse> notifications) { this.notifications = notifications; }

    public List<NotificationResponse> getNotificationsNonLues() { return notificationsNonLues; }
    public void setNotificationsNonLues(List<NotificationResponse> notificationsNonLues) { this.notificationsNonLues = notificationsNonLues; }

    public List<NotificationResponse> getNotificationsEnAttente() { return notificationsEnAttente; }
    public void setNotificationsEnAttente(List<NotificationResponse> notificationsEnAttente) { this.notificationsEnAttente = notificationsEnAttente; }

    public NotificationResponse getNotificationSelectionnee() { return notificationSelectionnee; }
    public void setNotificationSelectionnee(NotificationResponse notificationSelectionnee) { this.notificationSelectionnee = notificationSelectionnee; }

    public String getFiltreType() { return filtreType; }
    public void setFiltreType(String filtreType) { this.filtreType = filtreType; }

    public CreateNotificationRequest getNouvelleNotification() { return nouvelleNotification; }
    public void setNouvelleNotification(CreateNotificationRequest nouvelleNotification) { this.nouvelleNotification = nouvelleNotification; }
    
    public NotificationService.NotificationGroupeeRequest getNotificationGroupee() { return notificationGroupee; }
    public void setNotificationGroupee(NotificationService.NotificationGroupeeRequest notificationGroupee) { this.notificationGroupee = notificationGroupee; }
    
    public int getNombreNotificationsNonLues() {
        return notificationsNonLues != null ? notificationsNonLues.size() : 0;
    }
    
    /**
     * Actualise les données depuis le backend
     */
    public void actualiser() {
        chargerNotifications();
        chargerNotificationsNonLues();
        chargerNotificationsEnAttente();
        errorHandler.showSuccess("Succès", "Données actualisées");
    }
}

