package dev.lions.unionflow.client.view;

import io.quarkus.security.identity.SecurityIdentity;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.io.IOException;
import java.io.Serializable;
import org.jboss.logging.Logger;

/**
 * Bean de gestion de l'authentification via Keycloak OIDC
 * 
 * <p>
 * Utilise {@link SecurityIdentity} au lieu de {@code JsonWebToken} car
 * l'application est en mode OIDC {@code web-app} (authorization code flow),
 * et non en mode {@code service} (bearer token flow).
 * 
 * @author UnionFlow Team
 * @version 2.1
 */
@Named("loginBean")
@RequestScoped
public class LoginBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(LoginBean.class);

    @Inject
    SecurityIdentity securityIdentity;

    @Inject
    private UserSession userSession;

    /**
     * Redirige vers Keycloak pour l'authentification
     * L'authentification est gérée automatiquement par Quarkus OIDC
     */
    public void login() {
        try {
            // La redirection vers Keycloak est gérée automatiquement par Quarkus OIDC
            // via la configuration dans application.properties
            LOG.info("Redirection vers Keycloak pour l'authentification");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la redirection vers Keycloak");
        }
    }

    /**
     * Déconnexion de l'utilisateur
     * Invalide la session JSF et redirige vers l'endpoint de déconnexion OIDC
     */
    public void logout() {
        try {
            LOG.info("Déconnexion de l'utilisateur: " +
                    (securityIdentity != null ? securityIdentity.getPrincipal().getName() : "unknown"));

            // Nettoyer la session locale
            if (userSession != null) {
                userSession.clearSession();
            }

            // Invalider la session JSF avant la redirection
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ExternalContext externalContext = facesContext.getExternalContext();

            // Récupérer la session et l'invalider
            externalContext.invalidateSession();

            // Construire l'URL de retour après déconnexion
            String baseUrl = externalContext.getRequestScheme() + "://" +
                           externalContext.getRequestServerName() + ":" +
                           externalContext.getRequestServerPort() +
                           externalContext.getRequestContextPath();

            String postLogoutRedirectUri = baseUrl + "/index.xhtml";

            // Redirection vers l'endpoint OIDC de déconnexion Quarkus
            // Quarkus OIDC gère automatiquement la déconnexion Keycloak
            String logoutUrl = baseUrl + "/logout?post_logout_redirect_uri=" + postLogoutRedirectUri;

            LOG.info("Redirection vers: " + logoutUrl);

            externalContext.redirect(logoutUrl);
            facesContext.responseComplete();

        } catch (IOException e) {
            LOG.errorf(e, "Erreur lors de la redirection de déconnexion");

            // Fallback : retour à l'index
            try {
                FacesContext facesContext = FacesContext.getCurrentInstance();
                if (facesContext != null) {
                    ExternalContext externalContext = facesContext.getExternalContext();
                    String baseUrl = externalContext.getRequestScheme() + "://" +
                                   externalContext.getRequestServerName() + ":" +
                                   externalContext.getRequestServerPort() +
                                   externalContext.getRequestContextPath();
                    externalContext.redirect(baseUrl + "/index.xhtml");
                    facesContext.responseComplete();
                }
            } catch (IOException ex) {
                LOG.error("Erreur lors de la redirection fallback", ex);
            }
        }
    }

    /**
     * Vérifie si l'utilisateur est authentifié
     */
    public boolean isAuthenticated() {
        return securityIdentity != null && !securityIdentity.isAnonymous();
    }
}
