package dev.lions.btpxpress.service;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Service de gestion des chantiers côté client.
 * <p>
 * Ce service encapsule la communication avec l'API backend pour les opérations
 * liées aux chantiers. Il utilise le REST Client pour effectuer les appels HTTP
 * vers le backend.
 * </p>
 *
 * @author BTP Xpress Development Team
 * @version 1.0.0
 * @since 1.0.0
 */
@ApplicationScoped
public class ChantierService {

    private static final Logger LOG = LoggerFactory.getLogger(ChantierService.class);

    @Inject
    @RestClient
    BtpXpressApiClient apiClient;

    /**
     * Récupère tous les chantiers depuis l'API backend.
     *
     * @return Liste des chantiers, ou liste vide en cas d'erreur.
     */
    public List<Map<String, Object>> getAllChantiers() {
        try {
            LOG.debug("Récupération de la liste des chantiers depuis l'API backend.");
            Response response = apiClient.getChantiers();
            if (response.getStatus() == Response.Status.OK.getStatusCode()) {
                @SuppressWarnings("unchecked")
                List<Map<String, Object>> chantiers = response.readEntity(List.class);
                LOG.debug("Chantiers récupérés avec succès : {} élément(s)", chantiers != null ? chantiers.size() : 0);
                return chantiers != null ? chantiers : new ArrayList<>();
            } else {
                LOG.warn("Erreur lors de la récupération des chantiers. Code HTTP : {}", response.getStatus());
                return new ArrayList<>();
            }
        } catch (Exception e) {
            LOG.error("Erreur lors de la communication avec l'API backend pour récupérer les chantiers : {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * Récupère un chantier par son identifiant depuis l'API backend.
     *
     * @param id L'identifiant du chantier.
     * @return Le chantier sous forme de Map, ou null en cas d'erreur.
     */
    public Map<String, Object> getChantierById(Long id) {
        try {
            LOG.debug("Récupération du chantier avec ID : {}", id);
            Response response = apiClient.getChantier(id);
            if (response.getStatus() == Response.Status.OK.getStatusCode()) {
                @SuppressWarnings("unchecked")
                Map<String, Object> chantier = response.readEntity(Map.class);
                LOG.debug("Chantier récupéré avec succès.");
                return chantier;
            } else {
                LOG.warn("Erreur lors de la récupération du chantier. Code HTTP : {}", response.getStatus());
                return null;
            }
        } catch (Exception e) {
            LOG.error("Erreur lors de la communication avec l'API backend pour récupérer le chantier : {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * Crée un nouveau chantier via l'API backend.
     *
     * @param chantierData Les données du chantier à créer (Map ou DTO).
     * @return Le chantier créé sous forme de Map, ou null en cas d'erreur.
     */
    public Map<String, Object> createChantier(Map<String, Object> chantierData) {
        try {
            LOG.debug("Création d'un nouveau chantier : {}", chantierData.get("nom"));
            Response response = apiClient.createChantier(chantierData);
            if (response.getStatus() == Response.Status.CREATED.getStatusCode() || 
                response.getStatus() == Response.Status.OK.getStatusCode()) {
                @SuppressWarnings("unchecked")
                Map<String, Object> chantier = response.readEntity(Map.class);
                LOG.info("Chantier créé avec succès : {}", chantier.get("id"));
                return chantier;
            } else {
                String errorMessage = response.readEntity(String.class);
                LOG.warn("Erreur lors de la création du chantier. Code HTTP : {}, Message : {}", 
                    response.getStatus(), errorMessage);
                return null;
            }
        } catch (Exception e) {
            LOG.error("Erreur lors de la communication avec l'API backend pour créer le chantier : {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * Met à jour un chantier existant via l'API backend.
     *
     * @param id L'identifiant du chantier (UUID en String).
     * @param chantierData Les nouvelles données du chantier (Map ou DTO).
     * @return Le chantier mis à jour sous forme de Map, ou null en cas d'erreur.
     */
    public Map<String, Object> updateChantier(String id, Map<String, Object> chantierData) {
        try {
            LOG.debug("Mise à jour du chantier avec ID : {}", id);
            Response response = apiClient.updateChantier(id, chantierData);
            if (response.getStatus() == Response.Status.OK.getStatusCode()) {
                @SuppressWarnings("unchecked")
                Map<String, Object> chantier = response.readEntity(Map.class);
                LOG.info("Chantier mis à jour avec succès : {}", id);
                return chantier;
            } else {
                String errorMessage = response.readEntity(String.class);
                LOG.warn("Erreur lors de la mise à jour du chantier. Code HTTP : {}, Message : {}", 
                    response.getStatus(), errorMessage);
                return null;
            }
        } catch (Exception e) {
            LOG.error("Erreur lors de la communication avec l'API backend pour mettre à jour le chantier : {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * Supprime un chantier via l'API backend.
     *
     * @param id L'identifiant du chantier (UUID en String).
     * @param permanent Si true, suppression définitive, sinon suppression logique (défaut: false).
     * @return true si la suppression a réussi, false sinon.
     */
    public boolean deleteChantier(String id, boolean permanent) {
        try {
            LOG.debug("Suppression du chantier avec ID : {} (permanent: {})", id, permanent);
            Response response = apiClient.deleteChantier(id, permanent);
            if (response.getStatus() == Response.Status.NO_CONTENT.getStatusCode() || 
                response.getStatus() == Response.Status.OK.getStatusCode()) {
                LOG.info("Chantier supprimé avec succès : {}", id);
                return true;
            } else {
                String errorMessage = response.readEntity(String.class);
                LOG.warn("Erreur lors de la suppression du chantier. Code HTTP : {}, Message : {}", 
                    response.getStatus(), errorMessage);
                return false;
            }
        } catch (Exception e) {
            LOG.error("Erreur lors de la communication avec l'API backend pour supprimer le chantier : {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * Supprime un chantier via l'API backend (suppression logique par défaut).
     *
     * @param id L'identifiant du chantier (UUID en String).
     * @return true si la suppression a réussi, false sinon.
     */
    public boolean deleteChantier(String id) {
        return deleteChantier(id, false);
    }
}

