package incheon.product.common.geo3d;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * 외부 API REST 클라이언트.
 * 타임아웃/재시도 설정을 통합하여 단일 Bean으로 제공한다.
 *
 * <p>기존 코드에서 각 ServiceImpl마다 {@code new RestTemplate()}을 인라인 생성하던 패턴을
 * 이 Bean으로 통합하여 설정 일관성과 유지보수성을 높인다.</p>
 *
 * <ul>
 *   <li>ITS 교통/CCTV API 호출 (TrafficServiceImpl, CctvServiceImpl)</li>
 *   <li>GIS Manager API 호출 (Data3DServiceImpl, Data3DApiController)</li>
 * </ul>
 */
@Slf4j
@Component("productExternalApiClient")
public class ExternalApiClient {

    @Resource(name = "geoView3DProperties")
    private GeoView3DProperties properties;

    /** ITS API 전용 RestTemplate (타임아웃 설정 적용) */
    private RestTemplate itsRestTemplate;

    /** GIS Manager 전용 RestTemplate (GisManager 설정 타임아웃 적용) */
    private RestTemplate gisRestTemplate;

    @PostConstruct
    public void init() {
        GeoView3DProperties.TrafficApi apiConfig = properties.getTrafficApi();

        SimpleClientHttpRequestFactory itsFactory = new SimpleClientHttpRequestFactory();
        itsFactory.setConnectTimeout(apiConfig.getConnectTimeoutMs());
        itsFactory.setReadTimeout(apiConfig.getReadTimeoutMs());
        this.itsRestTemplate = new RestTemplate(itsFactory);

        GeoView3DProperties.GisManager gisConfig = properties.getGisManager();
        SimpleClientHttpRequestFactory gisFactory = new SimpleClientHttpRequestFactory();
        gisFactory.setConnectTimeout(gisConfig.getConnectTimeoutMs());
        gisFactory.setReadTimeout(gisConfig.getReadTimeoutMs());
        this.gisRestTemplate = new RestTemplate(gisFactory);
    }

    /**
     * ITS API GET 호출.
     * TrafficApi 설정의 타임아웃이 적용된 RestTemplate을 사용한다.
     *
     * @param url 요청 URL
     * @param responseType 응답 타입
     * @return 응답 본문
     */
    public <T> T getForIts(String url, Class<T> responseType) {
        return itsRestTemplate.getForObject(url, responseType);
    }

    /**
     * GIS Manager API 호출 (임의 HTTP Method).
     *
     * @param url 요청 URL
     * @param method HTTP 메서드
     * @param requestEntity 요청 엔티티 (nullable)
     * @param responseType 응답 타입
     * @return ResponseEntity
     */
    public <T> ResponseEntity<T> exchangeForGis(String url, HttpMethod method,
                                                  HttpEntity<?> requestEntity, Class<T> responseType) {
        return gisRestTemplate.exchange(url, method, requestEntity, responseType);
    }
}
