package org.mte.numecoeval.calculs.infrastructure.client;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.calculs.domain.exception.ExternalApiException;
import org.mte.numecoeval.calculs.domain.utils.Constants;
import org.mte.numecoeval.calculs.referentiels.generated.api.client.InterneNumEcoEvalApi;
import org.mte.numecoeval.calculs.referentiels.generated.api.model.*;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClientResponseException;

import java.util.List;

@Slf4j
@Service
@AllArgsConstructor
public class ReferentielClient {

    private InterneNumEcoEvalApi interneNumEcoEvalApi;

    @Cacheable("Etapes")
    public List<EtapeDTO> getEtapes() {

        try {
            var result = interneNumEcoEvalApi.getAllEtapes().collectList().block();
            return result == null ? List.of() : result;
        } catch (WebClientResponseException e) {
            if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                throw new ExternalApiException(e);
            }
        }
        return List.of();
    }

    @Cacheable("Criteres")
    public List<CritereDTO> getCriteres() {
        try {
            var result = interneNumEcoEvalApi.getAllCriteres().collectList().block();
            return result == null ? List.of() : result;
        } catch (WebClientResponseException e) {
            if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                throw new ExternalApiException(e);
            }
        }
        return List.of();
    }

    @Cacheable(value = "Hypothese")
    public HypotheseDTO getHypothese(String code, String nomOrganisation) {
        for (String nomOrg : List.of(nomOrganisation, "")) {
            try {
                var hy = interneNumEcoEvalApi.getHypothese(code, nomOrg).block();
                if (hy != null) {
                    return hy;
                }
            } catch (WebClientResponseException e) {
                if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                    throw new ExternalApiException(e);
                }
            }
        }
        return null;
    }

    @Cacheable(value = "CorrespondanceRefEquipement")
    public CorrespondanceRefEquipementDTO getCorrespondanceRefEquipement(String modele, String nomOrganisation) {
        for (String nomOrg : List.of(nomOrganisation, "")) {
            try {
                var corr = interneNumEcoEvalApi.getCorrespondanceRefEquipement(modele, nomOrg).block();
                if (corr != null) {
                    return corr;
                }
            } catch (WebClientResponseException e) {
                if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                    throw new ExternalApiException(e);
                }
            }
        }
        return null;
    }

    @Cacheable(value = "TypeItem")
    public TypeItemDTO getTypeItem(String type, String nomOrganisation) {
        for (String nomOrg : List.of(nomOrganisation, "")) {
            try {
                var ti = interneNumEcoEvalApi.getTypeItem(type, nomOrg).block();
                if (ti != null) {
                    return ti;
                }
            } catch (WebClientResponseException e) {
                if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                    throw new ExternalApiException(e);
                }
            }
        }
        return null;
    }

    @Cacheable(value = "FacteurCaracterisationMixElec")
    public FacteurCaracterisationDTO getMixElectriqueFromFacteurCaracterisation(String critere, String localisation, String nomOrganisation) {
        for (String nomOrg : List.of(nomOrganisation, "")) {
            try {
                var fc = interneNumEcoEvalApi.getFacteurCaracterisation(critere, null, null, localisation, Constants.ELECTRICITY_MIX_CATEGORY, nomOrg).blockFirst();
                if (fc != null) {
                    return fc;
                }
            } catch (WebClientResponseException e) {
                if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                    throw new ExternalApiException(e);
                }
            }
        }
        return null;
    }

    @Cacheable(value = "FacteurCaracterisation")
    public FacteurCaracterisationDTO getFacteurCaracterisationByCritereAndEtapeAndNomAndNomOrganisation(String critere, String etape, String nom, String nomOrganisation) {
        for (String nomOrg : List.of(nomOrganisation, "")) {
            try {
                var fc = interneNumEcoEvalApi.getFacteurCaracterisation(critere, etape, nom, null, null, nomOrg).blockFirst();
                if (fc != null) {
                    return fc;
                }
            } catch (WebClientResponseException e) {
                if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                    throw new ExternalApiException(e);
                }
            }
        }
        return null;
    }


    @Cacheable(value = "ImpactMessagerie")
    public ImpactMessagerieDTO getMessagerie(String critere) {
        try {
            return interneNumEcoEvalApi.getImpactMessagerie(critere).block();
        } catch (WebClientResponseException e) {
            if (e.getStatusCode() != HttpStatusCode.valueOf(404)) {
                throw new ExternalApiException(e);
            }
        }
        return null;
    }
}
