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

import dev.lions.user.manager.client.service.RealmServiceClient;
import dev.lions.user.manager.client.service.UserServiceClient;
import dev.lions.user.manager.dto.user.UserDTO;
import dev.lions.user.manager.enums.user.StatutUser;
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.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

/**
 * Bean JSF pour la création d'un nouvel utilisateur
 * 
 * @author Lions User Manager
 * @version 1.0.0
 */
@Named("userCreationBean")
@ViewScoped
@Data
public class UserCreationBean implements Serializable {

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

    @Inject
    @RestClient
    private UserServiceClient userServiceClient;

    @Inject
    @RestClient
    private RealmServiceClient realmServiceClient;

    private UserDTO newUser = UserDTO.builder().build();
    // Par défaut, utiliser le realm lions-user-manager où les utilisateurs sont configurés
    private String realmName = "lions-user-manager";
    private String password;
    private String passwordConfirm;

    // Options pour les selects
    private List<StatutUser> statutOptions = List.of(StatutUser.values());
    private List<String> availableRealms = new ArrayList<>();

    @PostConstruct
    public void init() {
        loadRealms();
        // Initialiser les valeurs par défaut
        newUser.setEnabled(true);
        newUser.setEmailVerified(false);
        newUser.setStatut(StatutUser.ACTIF);
    }

    /**
     * Créer un nouvel utilisateur
     */
    public String createUser() {
        // Validation
        if (password == null || password.isEmpty()) {
            addErrorMessage("Le mot de passe est obligatoire");
            return null;
        }

        if (!password.equals(passwordConfirm)) {
            addErrorMessage("Les mots de passe ne correspondent pas");
            return null;
        }

        if (password.length() < 8) {
            addErrorMessage("Le mot de passe doit contenir au moins 8 caractères");
            return null;
        }

        try {
            // Créer l'utilisateur
            UserDTO createdUser = userServiceClient.createUser(newUser, realmName);

            // Définir le mot de passe
            UserServiceClient.PasswordResetRequest passwordRequest = new UserServiceClient.PasswordResetRequest();
            passwordRequest.password = password;
            passwordRequest.temporary = true;
            userServiceClient.resetPassword(createdUser.getId(), realmName, passwordRequest);

            addSuccessMessage("Utilisateur créé avec succès: " + createdUser.getUsername());
            resetForm();
            return "userListPage"; // Rediriger vers la liste
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la création: " + e.getMessage());
            addErrorMessage("Erreur lors de la création: " + e.getMessage());
            return null;
        }
    }

    /**
     * Réinitialiser le formulaire
     */
    public void resetForm() {
        newUser = UserDTO.builder().build();
        password = null;
        passwordConfirm = null;
        newUser.setEnabled(true);
        newUser.setEmailVerified(false);
        newUser.setStatut(StatutUser.ACTIF);
    }

    /**
     * Annuler la création
     */
    public String cancel() {
        resetForm();
        return "userListPage";
    }

    /**
     * Valider la correspondance des mots de passe en temps réel
     */
    public void validatePasswordMatch() {
        FacesContext context = FacesContext.getCurrentInstance();

        // Vérifier que les deux champs sont remplis
        if (password != null && !password.isEmpty() &&
            passwordConfirm != null && !passwordConfirm.isEmpty()) {

            // Vérifier la correspondance
            if (!password.equals(passwordConfirm)) {
                context.addMessage("formUserCreation:passwordConfirm",
                    new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "Erreur",
                        "Les mots de passe ne correspondent pas"));
            } else {
                // Succès - afficher message de confirmation
                context.addMessage("formUserCreation:passwordConfirm",
                    new FacesMessage(FacesMessage.SEVERITY_INFO,
                        "Validé",
                        "Les mots de passe correspondent"));
            }
        }
    }

    /**
     * Charger les realms disponibles depuis Keycloak
     */
    private void loadRealms() {
        try {
            LOGGER.info("Chargement des realms disponibles depuis Keycloak");
            List<String> realms = realmServiceClient.getAllRealms();
            
            if (realms == null || realms.isEmpty()) {
                LOGGER.warning("Aucun realm trouvé dans Keycloak");
                availableRealms = Collections.emptyList();
            } else {
                availableRealms = new ArrayList<>(realms);
                LOGGER.info("Realms disponibles chargés depuis Keycloak: " + availableRealms.size());
                
                // Définir le premier realm comme realm par défaut si aucun n'est sélectionné
                if (!availableRealms.isEmpty() && (realmName == null || realmName.isEmpty())) {
                    realmName = availableRealms.get(0);
                }
            }
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des realms depuis Keycloak: " + e.getMessage());
            LOGGER.log(java.util.logging.Level.SEVERE, "Exception complète", e);
            // Fallback: liste vide plutôt que des données fictives
            availableRealms = Collections.emptyList();
        }
    }

    // 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));
    }
}

