package com.imprimelibros.erp.externalApi; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; import java.util.HashMap; import java.util.function.Supplier; import java.util.List; @Service public class skApiClient { @Value("${safekat.api.url}") private String skApiUrl; private final AuthService authService; private final RestTemplate restTemplate; public skApiClient(AuthService authService) { this.authService = authService; this.restTemplate = new RestTemplate(); } public String getPrice(Map requestBody) { return performWithRetry(() -> { String url = this.skApiUrl + "api/calcular"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(authService.getToken()); HttpEntity> entity = new HttpEntity<>(requestBody, headers); ResponseEntity response = restTemplate.exchange( url, HttpMethod.POST, entity, String.class); return response.getBody(); }); } public Integer getMaxSolapas(Map requestBody) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(authService.getToken()); Map request = new HashMap<>(requestBody); Map data = new HashMap<>(); try { String jsonResponse = performWithRetry(() -> { String url = this.skApiUrl + "api/calcular-solapas"; data.put("clienteId", request.get("clienteId")); data.put("tamanio", (Map) request.get("tamanio")); data.put("tirada", requestBody.get("tirada")); data.put("paginas", request.get("paginas")); data.put("paginasColor", request.get("paginasColor")); data.put("papelInteriorDiferente", 0); data.put("paginasCuadernillo", request.get("paginasCuadernillo")); data.put("tipo", request.get("tipo")); data.put("isColor", request.get("isColor")); data.put("isHq", request.get("isHq")); data.put("interior", request.get("interior")); HttpEntity> entity = new HttpEntity<>(data, headers); ResponseEntity response = restTemplate.exchange( url, HttpMethod.POST, entity, String.class); return response.getBody(); }); ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(jsonResponse); if (root.get("data") == null || !root.get("data").isInt()) { throw new RuntimeException("Respuesta inesperada de calcular-solapas: " + jsonResponse); } int solapas = root.get("data").asInt(); return solapas; } catch (JsonProcessingException e) { // No se puede calcular el interior, por lo que las solapas seran el 80% del // ancho Map tamanio = (Map)data.get("tamanio"); if (tamanio == null || tamanio.get("ancho") == null) throw new RuntimeException("Tamaño no válido en la solicitud: " + data); else { int ancho = (int) tamanio.get("ancho"); return (int) Math.floor(ancho * 0.8); // 80% del ancho } } } /****************** * PRIVATE METHODS ******************/ private String performWithRetry(Supplier request) { try { return request.get(); } catch (HttpClientErrorException.Unauthorized e) { // Token expirado, renovar y reintentar authService.invalidateToken(); try { return request.get(); // segundo intento } catch (HttpClientErrorException ex) { throw new RuntimeException("La autenticación ha fallado tras renovar el token.", ex); } } } }