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

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;

/**
 * Mapper d'exceptions pour les clients REST
 * Convertit les réponses HTTP d'erreur en exceptions appropriées
 */
public class RestClientExceptionMapper implements ResponseExceptionMapper<RuntimeException> {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public RuntimeException toThrowable(Response response) {
        int status = response.getStatus();
        String reasonPhrase = response.getStatusInfo().getReasonPhrase();
        
        // Lire le corps de la réponse pour plus de détails
        String errorMessage = reasonPhrase;
        try {
            if (response.hasEntity()) {
                String body = response.readEntity(String.class);
                if (body != null && !body.isEmpty()) {
                    // Essayer de parser le JSON pour extraire le message
                    try {
                        JsonNode jsonNode = objectMapper.readTree(body);
                        if (jsonNode.has("message")) {
                            errorMessage = jsonNode.get("message").asText();
                        } else {
                            errorMessage = body;
                        }
                    } catch (Exception e) {
                        // Si ce n'est pas du JSON, utiliser le body tel quel
                        errorMessage = body;
                    }
                }
            }
        } catch (Exception e) {
            // Ignorer les erreurs de lecture du body
        }
        
        return switch (status) {
            case 400 -> new BadRequestException("Requête invalide: " + errorMessage);
            case 401 -> new UnauthorizedException("Non autorisé: " + errorMessage);
            case 403 -> new ForbiddenException("Accès interdit: " + errorMessage);
            case 404 -> new NotFoundException(errorMessage);
            case 409 -> new ConflictException("Conflit: " + errorMessage);
            case 422 -> new UnprocessableEntityException("Données non valides: " + errorMessage);
            case 500 -> new InternalServerErrorException("Erreur serveur interne: " + errorMessage);
            case 502 -> new BadGatewayException("Erreur de passerelle: " + errorMessage);
            case 503 -> new ServiceUnavailableException("Service indisponible: " + errorMessage);
            case 504 -> new GatewayTimeoutException("Timeout de passerelle: " + errorMessage);
            default -> new UnknownHttpStatusException("Erreur HTTP " + status + ": " + errorMessage);
        };
    }
    
    @Override
    public boolean handles(int status, MultivaluedMap<String, Object> headers) {
        // Gérer tous les codes d'erreur HTTP (>= 400)
        return status >= 400;
    }
    
    // Classes d'exception personnalisées
    public static class BadRequestException extends RuntimeException {
        public BadRequestException(String message) { super(message); }
    }
    
    public static class UnauthorizedException extends RuntimeException {
        public UnauthorizedException(String message) { super(message); }
    }
    
    public static class ForbiddenException extends RuntimeException {
        public ForbiddenException(String message) { super(message); }
    }
    
    public static class NotFoundException extends RuntimeException {
        public NotFoundException(String message) { super(message); }
    }
    
    public static class ConflictException extends RuntimeException {
        public ConflictException(String message) { super(message); }
    }
    
    public static class UnprocessableEntityException extends RuntimeException {
        public UnprocessableEntityException(String message) { super(message); }
    }
    
    public static class InternalServerErrorException extends RuntimeException {
        public InternalServerErrorException(String message) { super(message); }
    }
    
    public static class BadGatewayException extends RuntimeException {
        public BadGatewayException(String message) { super(message); }
    }
    
    public static class ServiceUnavailableException extends RuntimeException {
        public ServiceUnavailableException(String message) { super(message); }
    }
    
    public static class GatewayTimeoutException extends RuntimeException {
        public GatewayTimeoutException(String message) { super(message); }
    }
    
    public static class UnknownHttpStatusException extends RuntimeException {
        public UnknownHttpStatusException(String message) { super(message); }
    }
}

