package application.usecase;

import application.exception.GatewayServiceException;
import application.port.input.IValidateProfile;
import application.port.input.command.ValidateProfileCommand;
import com.banesco.common.infraestructure.helpers.LoggerHelper;
import domain.model.ClientProfile;
import domain.repository.IValidateProfilePort;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.Optional;

@Slf4j
@ApplicationScoped
public class ValidateProfileUseCase implements IValidateProfile {

    private final IValidateProfilePort validateProfilePort;

    @Inject
    public ValidateProfileUseCase(IValidateProfilePort validateProfilePort) {
        this.validateProfilePort = validateProfilePort;
    }

    /**
     * Orquesta la validación del perfil de un cliente.
     * Determina si un perfil es válido según la respuesta de un servicio externo,
     * navegando de forma segura a través de una estructura de datos anidada.
     *
     * @param command El comando con los datos de entrada para la validación.
     * @param requestId El ID de la solicitud para trazabilidad.
     * @return {@code true} si el perfil es válido (status = 0), {@code false} en cualquier otro caso.
     */
    @Override
    public Boolean execute(ValidateProfileCommand command, String requestId) {
        log.debug(LoggerHelper.buildInfoPrivateRequest(requestId, "Iniciando caso de uso: Validate Profile"));
        try {
            var result = validateProfilePort.execute(command, requestId);

            // La validación completa se realiza en una única cadena funcional y segura.
            var isValidProfile = Optional.ofNullable(result)
                    .filter(profile -> !profile.getHasError())
                    .flatMap(this::extractStatusFromData)
                    .map(status -> status == 0)
                    .orElse(false);

            log.info("{} - Validacion de perfil completada ¿Es valido?: {}", requestId, isValidProfile);
            return isValidProfile;

        } catch (GatewayServiceException ex) {
            log.error(LoggerHelper.buildError(requestId, "Fallo la comunicacion con el servicio de Validate Profile"));
            throw ex;
        } finally {
            log.debug(LoggerHelper.buildInfoPrivateRequest(requestId, "Finalizado caso de uso: Validate Profile"));
        }
    }

    /**
     * Helper privado para navegar de forma segura la estructura de Mapas anidada
     * y extraer el valor de 'stausu'.
     *
     * @param profile El objeto ClientProfile que contiene los datos.
     * @return Un Optional<Integer> con el valor de 'stausu' si se encuentra.
     */
    @SuppressWarnings("unchecked")
    private Optional<Integer> extractStatusFromData(ClientProfile profile) {
        return Optional.ofNullable(profile.getData())
                .filter(Map.class::isInstance).map(m -> (Map<String, Object>) m)
                .map(data -> data.get("banesco"))
                .filter(Map.class::isInstance).map(m -> (Map<String, Object>) m)
                .map(banesco -> banesco.get("respuesta"))
                .filter(Map.class::isInstance).map(m -> (Map<String, Object>) m)
                .map(res -> res.get("respuesta"))
                .filter(Map.class::isInstance).map(m -> (Map<String, Object>) m)
                .map(respuesta -> respuesta.get("stausu"))
                .filter(Integer.class::isInstance)
                .map(Integer.class::cast);
    }

}