package com.banesco.common.infrastructure.config;

import com.banesco.common.domain.model.DomainConfig;
import com.banesco.module.security_trace.domain.model.SecurityTraceConfig;
import com.banesco.module.service_status.domain.model.ServiceStatusConfig;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.config.Config;

import java.util.Map;

@Slf4j
@ApplicationScoped
@RegisterForReflection
public class RestClientConfig {

    private final Config config;
    private final ObjectMapper objectMapper;

    private static final String API_BASE = "api.rest-client.";
    private static final String API_DOMAIN_NAME = "dom-legal-customer-product-directory";
    private static final String API_SECURITY_TRACE_NAME = "security-trace";
    private static final String API_SERVICE_STATUS_NAME = "service-status";

    @Inject
    public RestClientConfig(
        Config config,
        ObjectMapper objectMapper
    ) {
        this.config = config;
        this.objectMapper = objectMapper;
    }

    public DomainConfig getDomLegalCustomerConfig() {
        return getConfig(API_DOMAIN_NAME, DomainConfig.class);
    }

    public SecurityTraceConfig getSecurityTraceConfig() {
        return getConfig(API_SECURITY_TRACE_NAME, SecurityTraceConfig.class);
    }

    public ServiceStatusConfig getServiceStatusConfig() {
        return getConfig(API_SERVICE_STATUS_NAME, ServiceStatusConfig.class);
    }

    private <T> T getConfig(
        String configName,
        Class<T> configType
    ) {
        try {
            String fullConfigName = API_BASE + configName;
            String json = config.getValue(fullConfigName, String.class);
            log.info("Configurando {}: {}", fullConfigName, json);

            if (json == null || json.trim().isEmpty()) {
                throw new IllegalStateException("Configuracion no encontrada para: " + fullConfigName);
            }

            Map<String, Object> configMap = objectMapper.readValue(json, new TypeReference<>() {});
            return objectMapper.convertValue(configMap, configType);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("Formato JSON invalido para " + configName + ": " + e.getMessage(), e);
        } catch (Exception e) {
            throw new IllegalStateException("Error cargando configuracion del servicio " + configName + ": " + e.getMessage(), e);
        }
    }

    public String toJsonString(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            log.error("Error al convertir a json string: {}", e.getMessage());
            return null;
        }
    }
}