package com.banesco.module.service_status.infrastructure.client;

import com.banesco.common.application.usecase.HttpClientUseCase;
import com.banesco.common.domain.exception.HttpStatusCodeException;
import com.banesco.common.domain.model.HttpRequest;
import com.banesco.common.infrastructure.config.RestClientConfig;
import com.banesco.module.service_status.application.usecase.ServiceStatusUseCase;
import com.banesco.module.service_status.domain.dto.request.ServiceStatusRequest;
import com.banesco.module.service_status.domain.model.ServiceStatusConfig;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ApplicationScoped
public class ServiceStatusClient implements ServiceStatusUseCase {
    private final HttpClientUseCase httpClientUseCase;
    private final ServiceStatusConfig serviceStatusConfig;

    @Inject
    public ServiceStatusClient(
        HttpClientUseCase httpClientUseCase,
        RestClientConfig restClientConfig
    ) {
        this.httpClientUseCase = httpClientUseCase;
        this.serviceStatusConfig = restClientConfig.getServiceStatusConfig();
        log.info("Configuracion cargada para service-status: {}", serviceStatusConfig);
    }

    @Override
    public <T> T execute(
        ServiceStatusRequest params,
        Class<T> responseType
    ) {
        ServiceStatusRequest body = ServiceStatusRequest.builder()
            .applicationId(params.getApplicationId())
            .transactionId(params.getTransactionId())
            .bankService(serviceStatusConfig.getRequest().getBankService())
            .build();
        HttpRequest request = HttpRequest.forDirectResponse(
                serviceStatusConfig.getUrl(),
                HttpRequest.HttpMethod.POST,
                responseType
            )
            .withBody(body)
            .withTimeout(
                serviceStatusConfig.getTimeout().getConnect(),
                serviceStatusConfig.getTimeout().getResponse()
            );

        log.debug("Request configurado: {}", request);

        try {
            T response = httpClientUseCase.execute(request);

            log.info(
                "Solicitud de estado del servicio exitosa: {}",
                response.toString().contains("status=")
            );

            return response;
        } catch (HttpStatusCodeException e) {
            log.error(
                "Error HTTP ejecutando verificacion de estado del servicio: {} - {}",
                e.getStatusCode(),
                e.getMessage()
            );

            throw e;
        } catch (Exception e) {
            log.error("Error ejecutando verificacion de estado del servicio: {}", e.getMessage());
            throw HttpStatusCodeException.serviceUnavailable("503");
        }
    }
}