package com.gbcm.client.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import com.gbcm.server.api.dto.client.ClientDTO;
import com.gbcm.server.api.dto.client.CreateClientDTO;
import com.gbcm.server.api.dto.client.UpdateClientDTO;
import com.gbcm.server.api.dto.common.PagedResponseDTO;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

/**
 * Service REST client pour communiquer avec l'API clients du serveur GBCM.
 * Utilise MicroProfile REST Client pour les appels HTTP.
 * 
 * @author GBCM Development Team
 * @version 1.0
 * @since 1.0
 */
@ApplicationScoped
public class ClientRestService {

    private static final Logger logger = LoggerFactory.getLogger(ClientRestService.class);

    @Inject
    @RestClient
    private ClientRestClient clientRestClient;

    /**
     * Récupère la liste paginée des clients
     */
    public PagedResponseDTO<ClientDTO> getClients(int page, int size, String sort,
                                                  String status, String industry, String search) {
        try {
            logger.info("Appel API pour récupérer les clients - page: {}, size: {}", page, size);
            return clientRestClient.getClients(page, size, sort, status, industry, search);
        } catch (Exception e) {
            logger.error("Erreur lors de l'appel API getClients: " + e.getMessage(), e);
            throw new RuntimeException("Impossible de récupérer les clients", e);
        }
    }

    /**
     * Récupère un client par son ID
     */
    public ClientDTO getClientById(Long id) {
        try {
            logger.info("Appel API pour récupérer le client ID: {}", id);
            return clientRestClient.getClientById(id);
        } catch (Exception e) {
            logger.error("Erreur lors de l'appel API getClientById: " + e.getMessage(), e);
            throw new RuntimeException("Impossible de récupérer le client", e);
        }
    }

    /**
     * Crée un nouveau client
     */
    public ClientDTO createClient(CreateClientDTO createClientDTO) {
        try {
            logger.info("Appel API pour créer un client: {}", createClientDTO.getCompanyName());
            return clientRestClient.createClient(createClientDTO);
        } catch (Exception e) {
            logger.error("Erreur lors de l'appel API createClient: " + e.getMessage(), e);
            throw new RuntimeException("Impossible de créer le client", e);
        }
    }

    /**
     * Met à jour un client
     */
    public ClientDTO updateClient(Long id, UpdateClientDTO updateClientDTO) {
        try {
            logger.info("Appel API pour mettre à jour le client ID: {}", id);
            return clientRestClient.updateClient(id, updateClientDTO);
        } catch (Exception e) {
            logger.error("Erreur lors de l'appel API updateClient: " + e.getMessage(), e);
            throw new RuntimeException("Impossible de mettre à jour le client", e);
        }
    }

    /**
     * Interface REST Client pour les appels API
     */
    @RegisterRestClient
    @Path("/clients")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public interface ClientRestClient {

        @GET
        @Path("/dev")
        PagedResponseDTO<ClientDTO> getClients(
            @QueryParam("page") int page,
            @QueryParam("size") int size,
            @QueryParam("sort") String sort,
            @QueryParam("status") String status,
            @QueryParam("industry") String industry,
            @QueryParam("search") String search
        );

        @GET
        @Path("/{id}")
        ClientDTO getClientById(@PathParam("id") Long id);

        @POST
        ClientDTO createClient(CreateClientDTO createClientDTO);

        @PUT
        @Path("/{id}")
        ClientDTO updateClient(@PathParam("id") Long id, UpdateClientDTO updateClientDTO);
    }
}
