package infrastructure.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import domain.model.ErrorCode;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Getter
@ApplicationScoped
public class AppConfig {

    @Inject
    ObjectMapper objectMapper;

    @ConfigProperty(name = "app.response-json")
    private Optional<String> responseJsonString;

    @ConfigProperty(name = "app.print-response", defaultValue = "false")
    private Boolean printResponse;

    private List<ErrorCode> errorCodesList;
    private Map<String, ErrorCode> errorCodeMap;

    @PostConstruct
    public void init() {
        log.info("Inicializando configuracion de la aplicacion...");

        if (responseJsonString.isPresent() && !responseJsonString.get().isBlank()) {
            try {
                this.errorCodesList = objectMapper.readValue(responseJsonString.get(), new TypeReference<List<ErrorCode>>() {});
                this.errorCodeMap = this.errorCodesList.stream()
                        .collect(Collectors.toMap(
                                ErrorCode::backendCode,
                                Function.identity(),
                                (existing, replacement) -> existing
                        ));
                log.info("Se cargaron {} codigos de error en el mapa.", this.errorCodeMap.size());
            } catch (JsonProcessingException e) {
                log.error("Error fatal al parsear la propiedad 'app.response-json'.", e);
                this.errorCodesList = Collections.emptyList();
                this.errorCodeMap = Collections.emptyMap();
            }
        } else {
            log.warn("La propiedad 'app.response-json' no esta definida o esta vacia.");
            this.errorCodesList = Collections.emptyList();
            this.errorCodeMap = Collections.emptyMap();
        }

        log.info("--- Validando propiedades de configuracion ---");

        if (errorCodesList.isEmpty()) {
            log.warn("JSON de respuesta no configurado o vacio. El resolvedor de codigos podria no operar correctamente.");
        } else {
            log.info("Configuracion de 'app.response-json' validada.");
        }

        log.info("app.print-response configurado: {}", printResponse);

        log.info("Configuracion completada.");
    }

    public List<ErrorCode> getAppJson() {
        return errorCodesList;
    }

    public Map<String, ErrorCode> getErrorCodeMap() {
        return errorCodeMap;
    }

    public Boolean getPrintResponse() {
        return printResponse;
    }

}