package org.mte.numecoeval.expositiondonneesentrees.infrastructure.adapters;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.expositiondonneesentrees.domain.exception.RestException;
import org.mte.numecoeval.expositiondonneesentrees.domain.ports.output.ReferentielServicePort;
import org.mte.numecoeval.expositiondonneesentrees.referentiels.generated.api.client.InterneNumEcoEvalApi;
import org.mte.numecoeval.expositiondonneesentrees.referentiels.generated.api.model.*;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClientResponseException;

import java.util.List;

@Service
@Slf4j
@AllArgsConstructor
public class ReferentielRestClient implements ReferentielServicePort {

    private InterneNumEcoEvalApi interneNumEcoEvalApi;

    @Cacheable("hasMixElec")
    @Override
    public boolean hasMixElec(String pays) {

        boolean result = false;
        try {
            var res = interneNumEcoEvalApi.getMixElectriqueParPaysWithHttpInfo(pays).block();
            if (res == null || res.getBody() == null) return result;
            return !res.getBody().isEmpty();
        } catch (Exception e) {
            log.error("Une erreur est survenue lors de l'appel au référentiel mix electrique", e);
        }
        return result;
    }

    @Override
    public List<TypeEquipementDTO> getAllTypesEquipement() {
        var result = interneNumEcoEvalApi.getAllTypeEquipementWithHttpInfo().block();
        return result.getBody();
    }

    @Override
    public List<TypeItemDTO> getAllTypesItem() {
        var result = interneNumEcoEvalApi.getAllTypeItemWithHttpInfo().block();
        return result.getBody();
    }

    @Cacheable("CorrespondanceRefEquipement")
    @Override
    public CorrespondanceRefEquipementDTO getCorrespondance(String modele) {
        try {
            return interneNumEcoEvalApi.getCorrespondanceRefEquipement(modele).block();
        } catch (WebClientResponseException e) {
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return null;
            }
            throw new RestException(e);
        }
    }

    @Cacheable("ImpactEquipement")
    @Override
    public ImpactEquipementDTO getImpactEquipement(String refEquipement, String critere, String etape) {

        try {
            var res = interneNumEcoEvalApi.getImpactEquipement(refEquipement, critere, etape).block();
            if (res != null) {
                return res;
            }
        } catch (WebClientResponseException e) {
            if (e.getStatusCode() != HttpStatus.NOT_FOUND) {
                log.error("Une erreur est survenue lors de l'appel au référentiel impactequipement", e);
                return null;
            }
        }
        return null;
    }

    @Cacheable("FacteurCaracterisation")
    @Override
    public FacteurCaracterisationDTO getFacteurCaracterisation(String critere, String etape, String refEquipement) {

        try {
            var res = interneNumEcoEvalApi.getFacteurCaracterisation(critere, etape, refEquipement, null, null).blockFirst();
            if (res != null) {
                return res;
            }
        } catch (WebClientResponseException e) {
            if (e.getStatusCode() != HttpStatus.NOT_FOUND) {
                log.error("Une erreur est survenue lors de l'appel au référentiel facteurcaracterisation", e);
                return null;
            }
        }
        return null;
    }

    @Cacheable("Etapes")
    @Override
    public List<EtapeDTO> getAllEtapes() {
        return interneNumEcoEvalApi.getAllEtapesWithHttpInfo().block().getBody();
    }

    @Cacheable("Criteres")
    @Override
    public List<CritereDTO> getAllCriteres() {
        return interneNumEcoEvalApi.getAllCriteresWithHttpInfo().block().getBody();
    }
}
