package go.kr.project.common.service.impl;

import go.kr.project.common.service.AddressService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.web.util.UriComponentsBuilder;

import java.nio.charset.StandardCharsets;
import java.util.Collections;

/**
 * 주소 검색 서비스 구현 클래스
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AddressServiceImpl implements AddressService {

    // 중요로직: application.yml에서 API 키 주입
    @Value("${juso.api.key}")
    private String confmKey;

    @Value("${juso.api.url}")
    private String API_URL;

    @Override
    public String searchAddress(String keyword, int currentPage, int countPerPage) {
        log.debug("주소 API 호출: keyword={}, currentPage={}, countPerPage={}", keyword, currentPage, countPerPage);

        RestTemplate restTemplate = new RestTemplate();

        // HTTP 요청 헤더 설정
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        HttpEntity<String> entity = new HttpEntity<>(headers);

        // URI 및 파라미터 설정
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(API_URL)
                .queryParam("confmKey", confmKey)
                .queryParam("currentPage", currentPage)
                .queryParam("countPerPage", countPerPage)
                .queryParam("keyword", keyword)
                .queryParam("resultType", "json");

        try {
            // 중요로직: 외부 API 호출
            // 주소 API가 응답의 Content-Type을 text/html로 반환하는 경우가 있어, String으로 받은 후 그대로 전달
            ResponseEntity<String> response = restTemplate.exchange(
                    builder.encode(StandardCharsets.UTF_8).build().toUri(),
                    HttpMethod.GET,
                    entity,
                    String.class);

            // 중요로직: JSONP 콜백 형식 제거
            // juso.go.kr API는 resultType=json으로 요청 시 JSONP(jsonpCallback({...})) 형식으로 응답합니다.
            // 1차로 괄호'()'를 기준으로 파싱하고, 실패 시 2차로 중괄호'{}'를 기준으로 파싱하여 순수 JSON 문자열만 반환합니다.
            String responseBody = response.getBody();
            if (responseBody != null && !responseBody.trim().isEmpty()) {
                // 1차: 괄호'()'를 기준으로 JSONP 형식 파싱
                int startIndex = responseBody.indexOf('(');
                int endIndex = responseBody.lastIndexOf(')');

                if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
                    return responseBody.substring(startIndex + 1, endIndex);
                } else {
                    // 2차: 괄호가 없을 경우, 중괄호'{}'를 기준으로 순수 JSON 추출 시도
                    startIndex = responseBody.indexOf('{');
                    endIndex = responseBody.lastIndexOf('}');
                    if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
                        return responseBody.substring(startIndex, endIndex + 1);
                    }
                }
            }
            
            // JSONP 또는 JSON 형식이 아닌 경우, 원본 응답을 그대로 반환
            return responseBody;

        } catch (HttpClientErrorException e) {
            log.error("주소 API 호출 오류: {} - {}", e.getStatusCode(), e.getResponseBodyAsString());
            // 클라이언트에 전달할 에러 메시지 포맷 생성
            return String.format("{\"results\":{\"common\":{\"errorCode\":\"%s\",\"errorMessage\":\"%s\"}}}", 
                                 e.getStatusCode().value(), 
                                 "주소 API 서버로부터 오류 응답을 받았습니다: " + e.getStatusCode().getReasonPhrase());
        }
    }
}
