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

import dev.lions.user.manager.client.service.UserServiceClient;
import dev.lions.user.manager.dto.user.UserDTO;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
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 java.io.Serializable;
import java.util.logging.Logger;

/**
 * Bean JSF pour le profil et l'édition d'un utilisateur
 * 
 * @author Lions User Manager
 * @version 1.0.0
 */
@Named("userProfilBean")
@ViewScoped
@Data
public class UserProfilBean implements Serializable {

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

    @Inject
    @RestClient
    private UserServiceClient userServiceClient;

    private UserDTO user;
    private String userId;
    // Le realm "lions-user-manager" est le realm par défaut
    private String realmName = "lions-user-manager";
    private boolean editMode = false;

    // Pour la réinitialisation de mot de passe
    private String newPassword;
    private String newPasswordConfirm;

    @PostConstruct
    public void init() {
        // Récupérer l'ID depuis les paramètres de requête
        userId = FacesContext.getCurrentInstance().getExternalContext()
                .getRequestParameterMap().get("userId");

        // Récupérer le realm depuis les paramètres de requête (si présent)
        String realmParam = FacesContext.getCurrentInstance().getExternalContext()
                .getRequestParameterMap().get("realm");
        if (realmParam != null && !realmParam.isEmpty()) {
            this.realmName = realmParam;
        }

        if (userId != null && !userId.isEmpty()) {
            loadUser();
        } else {
            LOGGER.warning("Aucun userId fourni dans les paramètres");
        }
    }

    /**
     * Charger l'utilisateur
     */
    public void loadUser() {
        try {
            user = userServiceClient.getUserById(userId, realmName);
            if (user != null) {
                LOGGER.info("Utilisateur chargé: " + user.getUsername());
            }
        } catch (dev.lions.user.manager.client.service.RestClientExceptionMapper.NotFoundException e) {
            LOGGER.warning("Utilisateur non trouvé: " + userId);
            addErrorMessage("Utilisateur non trouvé dans le realm " + realmName);
            user = null;
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement de l'utilisateur: " + e.getMessage());
            addErrorMessage("Erreur lors du chargement de l'utilisateur: " + e.getMessage());
        }
    }

    /**
     * Activer le mode édition
     */
    public void enableEditMode() {
        editMode = true;
    }

    /**
     * Désactiver le mode édition
     */
    public void cancelEdit() {
        editMode = false;
        loadUser(); // Recharger les données originales
    }

    /**
     * Mettre à jour l'utilisateur
     */
    public void updateUser() {
        try {
            user = userServiceClient.updateUser(userId, user, realmName);
            editMode = false;
            addSuccessMessage("Utilisateur mis à jour avec succès");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la mise à jour: " + e.getMessage());
            addErrorMessage("Erreur lors de la mise à jour: " + e.getMessage());
        }
    }

    /**
     * Réinitialiser le mot de passe
     */
    public void resetPassword() {
        if (newPassword == null || newPassword.isEmpty()) {
            addErrorMessage("Le mot de passe ne peut pas être vide");
            return;
        }

        if (!newPassword.equals(newPasswordConfirm)) {
            addErrorMessage("Les mots de passe ne correspondent pas");
            return;
        }

        try {
            dev.lions.user.manager.dto.user.PasswordResetRequestDTO request = new dev.lions.user.manager.dto.user.PasswordResetRequestDTO(
                    newPassword, false);
            userServiceClient.resetPassword(userId, realmName, request);
            newPassword = null;
            newPasswordConfirm = null;
            addSuccessMessage("Mot de passe réinitialisé avec succès");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la réinitialisation: " + e.getMessage());
            addErrorMessage("Erreur lors de la réinitialisation: " + e.getMessage());
        }
    }

    /**
     * Activer l'utilisateur
     */
    public void activateUser() {
        try {
            userServiceClient.activateUser(userId, realmName);
            loadUser(); // Recharger pour mettre à jour le statut
            addSuccessMessage("Utilisateur activé avec succès");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'activation: " + e.getMessage());
            addErrorMessage("Erreur lors de l'activation: " + e.getMessage());
        }
    }

    /**
     * Désactiver l'utilisateur
     */
    public void deactivateUser() {
        try {
            userServiceClient.deactivateUser(userId, realmName, "Désactivé depuis le profil utilisateur");
            loadUser(); // Recharger pour mettre à jour le statut
            addSuccessMessage("Utilisateur désactivé avec succès");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la désactivation: " + e.getMessage());
            addErrorMessage("Erreur lors de la désactivation: " + e.getMessage());
        }
    }

    /**
     * Envoyer un email de vérification
     */
    public void sendVerificationEmail() {
        try {
            userServiceClient.sendVerificationEmail(userId, realmName);
            addSuccessMessage("Email de vérification envoyé");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'envoi: " + e.getMessage());
            addErrorMessage("Erreur lors de l'envoi: " + e.getMessage());
        }
    }

    /**
     * Supprimer l'utilisateur
     */
    public void deleteUser() {
        try {
            userServiceClient.deleteUser(userId, realmName, false);
            addSuccessMessage("Utilisateur supprimé avec succès");
            FacesContext.getCurrentInstance().getExternalContext().redirect("list.xhtml");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la suppression: " + e.getMessage());
            addErrorMessage("Erreur lors de la suppression: " + e.getMessage());
        }
    }

    // Méthodes compatibles avec user-actions.xhtml (qui passe l'ID en paramètre)

    public void activateUser(String userId) {
        activateUser();
    }

    public void deactivateUser(String userId) {
        deactivateUser();
    }

    public void resetPassword(String userId) {
        resetPassword();
    }

    public void deleteUser(String userId) {
        deleteUser();
    }

    /**
     * Déconnecter toutes les sessions
     */
    public void logoutAllSessions() {
        try {
            userServiceClient.logoutAllSessions(userId, realmName);
            addSuccessMessage("Toutes les sessions ont été déconnectées");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la déconnexion: " + e.getMessage());
            addErrorMessage("Erreur lors de la déconnexion: " + e.getMessage());
        }
    }

    public void logoutAllSessions(String userId) {
        logoutAllSessions();
    }

    // Méthodes utilitaires
    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));
    }
}
