package dev.lions.unionflow.server.service.support;

import dev.lions.unionflow.server.entity.Membre;
import dev.lions.unionflow.server.repository.MembreRepository;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.NotFoundException;
import org.eclipse.microprofile.jwt.JsonWebToken;
import org.jboss.logging.Logger;

import java.util.UUID;

/**
 * Helper CDI partagé pour les services sécurisés.
 *
 * <p>Factorise la résolution de l'email depuis le JWT Keycloak,
 * évitant la duplication entre {@code MembreDashboardService}
 * et {@code CompteAdherentService} (DRY).
 */
@ApplicationScoped
public class SecuriteHelper {

    private static final Logger LOG = Logger.getLogger(SecuriteHelper.class);

    @Inject
    SecurityIdentity securityIdentity;

    @Inject
    MembreRepository membreRepository;

    /**
     * Résout l'email du principal connecté depuis le JWT.
     *
     * <p>Priorité :
     * <ol>
     *   <li>Claim JWT {@code "email"} (valeur Keycloak de référence)</li>
     *   <li>Fallback sur {@code getPrincipal().getName()} (preferred_username)</li>
     * </ol>
     *
     * @return email ou null si identité indisponible
     */
    public String resolveEmail() {
        if (securityIdentity == null || securityIdentity.isAnonymous() || securityIdentity.getPrincipal() == null) {
            return null;
        }

        if (securityIdentity.getPrincipal() instanceof JsonWebToken jwt) {
            try {
                String email = jwt.getClaim("email");
                if (email != null && !email.isBlank()) {
                    return email;
                }
            } catch (Exception e) {
                LOG.debugf("Claim 'email' non disponible : %s", e.getMessage());
            }
        }

        String name = securityIdentity.getPrincipal().getName();
        return (name != null && !name.isBlank()) ? name : null;
    }

    /**
     * Résout l'ID du membre connecté depuis le JWT.
     *
     * @return UUID du membre
     * @throws NotFoundException si le membre n'existe pas
     */
    public UUID resolveMembreId() {
        String email = resolveEmail();
        if (email == null || email.isBlank()) {
            throw new NotFoundException("Identité non disponible");
        }

        Membre membre = membreRepository.findByEmail(email.trim())
            .or(() -> membreRepository.findByEmail(email.trim().toLowerCase()))
            .filter(m -> m.getActif() == null || m.getActif())
            .orElseThrow(() -> new NotFoundException("Membre non trouvé pour l'email: " + email));

        return membre.getId();
    }

    /**
     * Délègue la récupération des rôles à l'identité Quarkus.
     */
    public java.util.Set<String> getRoles() {
        return securityIdentity != null ? securityIdentity.getRoles() : java.util.Collections.emptySet();
    }
}
