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

import com.banesco.common.application.usecase.HttpClientUseCase;
import com.banesco.common.domain.exception.HttpApiResponseException;
import com.banesco.common.domain.exception.HttpStatusCodeException;
import com.banesco.common.domain.model.ApiResponse;
import com.banesco.common.domain.model.DominionConfig;
import com.banesco.common.domain.model.HttpRequest;
import com.banesco.common.domain.model.StatusResponse;
import com.banesco.common.infrastructure.config.RestClientConfig;
import com.banesco.module.legal_customer_product_directory.application.usecase.DomainUseCase;
import com.banesco.module.legal_customer_product_directory.domain.dto.request.LegalCustomerProductDirectoryRequest;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

@Slf4j
@ApplicationScoped
public class DomLegalCustomerDirectoryClient implements DomainUseCase {
    private final HttpClientUseCase httpClientUseCase;
    private final DominionConfig dominionConfig;

    @Inject
    public DomLegalCustomerDirectoryClient(
        HttpClientUseCase httpClientUseCase,
        RestClientConfig restClientConfig
    ) {
        this.httpClientUseCase = httpClientUseCase;
        this.dominionConfig = restClientConfig.getDomLegalCustomerConfig();
        log.info("Configuración cargada para bus-legal-customer-directory: {}", dominionConfig);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> ApiResponse<T> execute(
        LegalCustomerProductDirectoryRequest params,
        Class<T> responseType
    ) {
        String customerIbsNumber = params.getCustomerIbsNumber();

        log.info("Consultando información del cliente: {}", customerIbsNumber);

        HttpRequest request = HttpRequest.builder()
            .url(dominionConfig.getUrl())
            .method(HttpRequest.HttpMethod.GET)
            .pathParams(Map.of("customerIbsNumber", customerIbsNumber))
            .queryParams(params.toQueryString())
            .responseType(ApiResponse.class)
            .connectTimeout(dominionConfig.getTimeout().getConnect())
            .readTimeout(dominionConfig.getTimeout().getResponse())
            .build();

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

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

            log.info(
                "Solicitud del api de dominio exitoso: {} -> {}",
                response.getStatusResponse(),
                response.getData()
            );

            return response;
        } catch (HttpApiResponseException e) {
            log.error(
                "Error HTTP con ApiResponse consultando cliente {}: {}",
                customerIbsNumber,
                e.getApiResponse()
            );

            return (ApiResponse<T>) e.getApiResponse();
        } catch (HttpStatusCodeException e) {
            log.error(
                "Error HTTP consultando cliente {}: {} - {}",
                customerIbsNumber,
                e.getStatusCode(),
                e.getMessage()
            );

            return new ApiResponse<>(
                StatusResponse.builder()
                    .statusCode(String.valueOf(e.getStatusCode()))
                    .message(e.getMessage())
                    .build()
            );
        } catch (Exception e) {
            log.error("Error consultando cliente {}: {}", customerIbsNumber, e.getMessage());

            return new ApiResponse<>(StatusResponse.builder().statusCode("503").build());
        }
    }
}