package com.banesco.module.service_order_payment_search.infrastructure.adapter;

import com.banesco.common.application.helper.RequestValidatorHelper;
import com.banesco.common.domain.exception.HttpStatusCodeException;
import com.banesco.module.payment_order.application.usecase.PaymentOrderUseCase;
import com.banesco.module.payment_order.domain.dto.request.PaymentOrderRequest;
import com.banesco.module.payment_order.domain.model.PaymentOrderBol;
import com.banesco.module.payment_order.domain.model.PaymentOrderBole;
import com.banesco.module.service_order_payment_search.application.repository.ApiPrivateRepository;
import com.banesco.module.service_order_payment_search.domain.dto.request.ServiceOrderPaymentSearchRequest;
import com.banesco.module.service_order_payment_search.domain.model.ServicingOrderProcedure;
import com.banesco.module.service_order_payment_search.infrastructure.mapper.ServicingOrderMapper;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
@ApplicationScoped
public class ApiPrivateAdapter implements ApiPrivateRepository {
    private final RequestValidatorHelper requestValidatorHelper;
    private final PaymentOrderUseCase paymentOrderUseCase;

    @Inject
    public ApiPrivateAdapter(
        RequestValidatorHelper requestValidatorHelper,
        PaymentOrderUseCase paymentOrderUseCase
    ) {
        this.requestValidatorHelper = requestValidatorHelper;
        this.paymentOrderUseCase = paymentOrderUseCase;
    }

    @Override
    public List<ServicingOrderProcedure> execute(
        ServiceOrderPaymentSearchRequest request
    ) {
        PaymentOrderRequest paymentOrderRequest =
            ServicingOrderMapper.toPaymentRequest(request);

        if(requestValidatorHelper.isBole(request)) {
            log.info("Ejecutando API privada BOLE -> {}", request.getChannelCode());
            return executeBole(paymentOrderRequest);
        } else if(requestValidatorHelper.isBol(request)) {
            log.info("Ejecutando API privada BOL -> {}", request.getChannelCode());
            return executeBol(paymentOrderRequest);
        } else {
            throw HttpStatusCodeException.conflict("PIBE-00");
        }
    }

    private List<ServicingOrderProcedure> executeBole(
        PaymentOrderRequest request
    ) {
        List<PaymentOrderBole> response = paymentOrderUseCase.execute(
            request, PaymentOrderBole.class
        );

        log.info("Resultado de las transacciones obtenidas (BOLE): {}", response.size());

        validateResponseNotEmpty(response);

        return ServicingOrderMapper.toBoleModel(response);
    }

    private List<ServicingOrderProcedure> executeBol(
        PaymentOrderRequest request
    ) {
        List<PaymentOrderBol> response = paymentOrderUseCase.execute(
            request, PaymentOrderBol.class
        );

        log.info("Resultado de las transacciones obtenidas (BOL): {}", response.size());

        validateResponseNotEmpty(response);

        return ServicingOrderMapper.toBolModel(response);
    }

    private <T> void validateResponseNotEmpty(List<T> response) {
        if (response.isEmpty()) {
            throw HttpStatusCodeException.conflict("PIBE-00");
        }
    }
}
