package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.dto.auth.LoginRequest;
import dev.lions.unionflow.client.dto.auth.LoginResponse;
import dev.lions.unionflow.client.security.JwtTokenManager;
import dev.lions.unionflow.client.service.AuthenticationService;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.validation.Valid;
import java.io.Serializable;
import java.util.logging.Logger;

@Named("loginBean")
@RequestScoped
public class LoginBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = Logger.getLogger(LoginBean.class.getName());
    
    @Inject
    private UserSession userSession;
    
    @Inject
    private JwtTokenManager tokenManager;
    
    @Inject
    private AuthenticationService authService;
    
    private String username;
    private String password;
    private String typeCompte;
    private boolean rememberMe;
    
    public String login() {
        try {
            if (username == null || username.trim().isEmpty() || 
                password == null || password.trim().isEmpty() ||
                typeCompte == null || typeCompte.trim().isEmpty()) {
                
                addErrorMessage("Erreur de validation", "Tous les champs sont requis");
                return null;
            }
            
            LoginRequest loginRequest = new LoginRequest(username, password, typeCompte);
            loginRequest.setRememberMe(rememberMe);
            
            LoginResponse response = authService.authenticate(loginRequest);
            
            // Mettre à jour la session utilisateur
            userSession.updateFromLoginResponse(response);
            
            // Gérer les tokens JWT
            tokenManager.setTokens(response);
            
            LOGGER.info("Connexion réussie pour: " + username + " (Type: " + typeCompte + ")");
            
            addSuccessMessage("Connexion réussie", "Bienvenue " + userSession.getCurrentUser().getNomComplet());
            
            // Redirection selon le type de compte
            return getRedirectUrlForUserType(response.getUser().getTypeCompte());
            
        } catch (AuthenticationService.AuthenticationException e) {
            LOGGER.warning("Échec de l'authentification: " + e.getMessage());
            addErrorMessage("Erreur de connexion", e.getMessage());
            return null;
        } catch (Exception e) {
            LOGGER.severe("Erreur inattendue lors de la connexion: " + e.getMessage());
            addErrorMessage("Erreur système", "Une erreur inattendue s'est produite. Veuillez réessayer.");
            return null;
        }
    }
    
    public String loginDemo(String demoType) {
        try {
            String demoUsername;
            String demoPassword = "admin";
            
            switch (demoType) {
                case "SUPER_ADMIN":
                    demoUsername = "superadmin";
                    typeCompte = "SUPER_ADMIN";
                    break;
                case "ADMIN":
                    demoUsername = "admin";
                    typeCompte = "ADMIN_ENTITE";
                    break;
                case "MEMBRE":
                    demoUsername = "membre";
                    demoPassword = "membre";
                    typeCompte = "MEMBRE";
                    break;
                default:
                    addErrorMessage("Erreur", "Type de démo invalide");
                    return null;
            }
            
            this.username = demoUsername;
            this.password = demoPassword;
            
            return login();
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la connexion démo: " + e.getMessage());
            addErrorMessage("Erreur système", "Impossible de se connecter en mode démo");
            return null;
        }
    }
    
    public String logout() {
        try {
            // Invalider le token côté serveur si possible
            if (tokenManager.hasValidTokens()) {
                authService.logout(tokenManager.getAccessToken());
            }
            
            // Nettoyer la session locale
            tokenManager.clearTokens();
            userSession.clearSession();
            
            // Invalider la session JSF
            FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
            
            LOGGER.info("Déconnexion réussie");
            
            return "/pages/public/login?faces-redirect=true";
            
        } catch (Exception e) {
            LOGGER.warning("Erreur lors de la déconnexion: " + e.getMessage());
            
            // Même en cas d'erreur, invalider la session locale
            tokenManager.clearTokens();
            userSession.clearSession();
            FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
            
            return "/pages/public/login?faces-redirect=true";
        }
    }
    
    private String getRedirectUrlForUserType(String typeCompte) {
        if (typeCompte == null) {
            return "/pages/secure/dashboard?faces-redirect=true";
        }
        
        switch (typeCompte) {
            case "SUPER_ADMIN":
                return "/pages/super-admin/dashboard?faces-redirect=true";
            case "ADMIN_ENTITE":
                return "/pages/admin/dashboard?faces-redirect=true";
            case "MEMBRE":
                return "/pages/membre/dashboard?faces-redirect=true";
            default:
                return "/pages/secure/dashboard?faces-redirect=true";
        }
    }
    
    private void addErrorMessage(String summary, String detail) {
        FacesContext.getCurrentInstance().addMessage(null, 
            new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail));
    }
    
    private void addSuccessMessage(String summary, String detail) {
        FacesContext.getCurrentInstance().addMessage(null, 
            new FacesMessage(FacesMessage.SEVERITY_INFO, summary, detail));
    }
    
    // Getters et Setters
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public String getTypeCompte() {
        return typeCompte;
    }
    
    public void setTypeCompte(String typeCompte) {
        this.typeCompte = typeCompte;
    }
    
    public boolean isRememberMe() {
        return rememberMe;
    }
    
    public void setRememberMe(boolean rememberMe) {
        this.rememberMe = rememberMe;
    }
}