package com.banesco.infrastructure.rest.repositories;

import com.banesco.common.domain.dto.bian.device.JsonHelper;
import com.banesco.common.domain.dto.bian.device.LoggerHelper;
import com.banesco.common.domain.dto.bian.response.StatusResponse;
import com.banesco.common.domain.model.ApiConfig;
import com.banesco.commons.config.StatusCodes;
import com.banesco.commons.utils.ResponseUtil;
import com.banesco.infrastructure.dtos.card.UpdateCardStatusRequest;
import com.banesco.infrastructure.dtos.card.UpdateCardStatusResponse;
import com.banesco.infrastructure.dtos.osb.AdditionalStatus;
import com.banesco.infrastructure.dtos.osb.Status;
import com.banesco.infrastructure.rest.clients.BusUpdateCardStatusRestClient;
import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.ws.rs.ClientErrorException;
import jakarta.ws.rs.core.Response;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.rest.client.RestClientBuilder;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@RegisterForReflection
@Slf4j
public class PaymentCardRepository {


    private final BusUpdateCardStatusRestClient restClient;

    private final String OPERATION_NAME = "BUS_UPDATE_CARD_STATUS";


    public PaymentCardRepository(ApiConfig apiConfig) {

        restClient = RestClientBuilder.newBuilder().baseUri(
                        URI.create(apiConfig.getUrl())
                ).
                connectTimeout(apiConfig.getTimeout().getConnect(), TimeUnit.MILLISECONDS)
                .readTimeout(apiConfig.getTimeout().getResponse(), TimeUnit.MILLISECONDS)
                .build(BusUpdateCardStatusRestClient.class);

    }


    public StatusResponse updateCardStatus(UpdateCardStatusRequest request) {

        try {


            log.info(LoggerHelper.buildInfoPrivateRequest(request.getRequestId(), OPERATION_NAME, JsonHelper.getJsonFromObject(request)));

            Response responseHttp = restClient.invoke(request);

            UpdateCardStatusResponse response = responseHttp.readEntity(UpdateCardStatusResponse.class);
            log.info(LoggerHelper.buildInfoPrivateResponse(request.getRequestId(), OPERATION_NAME, JsonHelper.getJsonFromObject(response)));
    /*

            if (response.getStatus().getStatusCode() != null &&
                    response.getStatus().getStatusCode().equals("000")) {
                return ResponseUtil.mapResponse(request.getRequestId(), StatusCodes.SUCCESS_OPERATION);
            }

            return validateSoapResponseStatus(request.getRequestId(), response.getStatus());
            */
            return null;


        } catch (ClientErrorException e) {
            log.error(LoggerHelper.buildError(OPERATION_NAME + " - " + request.getRequestId(), "Error calling API: " + e.getMessage()));
            return ResponseUtil.mapErrorResponse(request.getRequestId(), StatusCodes.FAILED_DEPENDENCY);
        } catch (Exception e) {
            log.error(LoggerHelper.buildError(OPERATION_NAME + " - " + request.getRequestId(), "Error interno callig API: " + e.getMessage()));
            return ResponseUtil.mapErrorResponse(request.getRequestId(), StatusCodes.INTERNAL_ERROR);
        }

    }


    /**
     * Validate Property Status If has some error and throw Exception with Code  or join(-) codes is no equals to 000
     *
     * @param status
     */
    private StatusResponse validateSoapResponseStatus(String requestId, Status status) {

        // Get Back Error
        Map<String, String> errors = new HashMap<>();
        AdditionalStatus additionalStatus = null;
        if (status.getAdditionalStatus() != null) {
            for (AdditionalStatus additionalStatusCurrent : status.getAdditionalStatus()) {
                if (additionalStatusCurrent.getStatusCode().equals("000")) {
                    break;
                } else {
                    errors.put(additionalStatusCurrent.getStatusCode(), additionalStatusCurrent.getStatusCode());
                    if (additionalStatus == null) {
                        additionalStatus = additionalStatusCurrent;
                    }
                }
            }

        }
        if (!errors.values().isEmpty()) {
            /**
             * Concat errors
             */
            return new StatusResponse(
                    "error",
                    errors.values().stream().collect(Collectors.joining("-")).toString(),
                    additionalStatus.getStatusDesc(),
                    requestId
            );
        }

        return ResponseUtil.mapErrorResponse(requestId, StatusCodes.INTERNAL_ERROR);


    }
}
