package gc.mda.signal_batch.batch.reader;

import gc.mda.signal_batch.domain.vessel.dto.AisTargetApiResponse;
import gc.mda.signal_batch.domain.vessel.dto.AisTargetDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ItemReader;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * S&P Global AIS API Reader (Spring Batch ItemReader)
 *
 * API: POST /AisSvc.svc/AIS/GetTargetsEnhanced
 * 요청: {"sinceSeconds": "60"}
 * 응답: ~33,000건/분
 *
 * 동작:
 * - 첫 read() 호출 시 API를 한 번 호출하여 전체 데이터를 가져옴
 * - 이후 read() 호출마다 한 건씩 반환 (Spring Batch chunk 처리)
 * - 모든 데이터를 반환하면 null을 반환하여 Step 종료
 */
@Slf4j
public class AisTargetDataReader implements ItemReader<AisTargetDto> {

    private static final String API_PATH = "/AisSvc.svc/AIS/GetTargetsEnhanced";

    private final WebClient webClient;
    private final int sinceSeconds;

    private Iterator<AisTargetDto> iterator;
    private boolean fetched = false;

    public AisTargetDataReader(WebClient webClient, int sinceSeconds) {
        this.webClient = webClient;
        this.sinceSeconds = sinceSeconds;
    }

    @Override
    public AisTargetDto read() {
        if (!fetched) {
            List<AisTargetDto> data = fetchDataFromApi();
            this.iterator = data.iterator();
            this.fetched = true;
        }

        if (iterator != null && iterator.hasNext()) {
            return iterator.next();
        }

        // Step 종료 — 다음 실행을 위해 상태 리셋
        fetched = false;
        iterator = null;
        return null;
    }

    private List<AisTargetDto> fetchDataFromApi() {
        try {
            log.info("[AisTargetDataReader] API 호출 시작: POST {} (sinceSeconds: {})",
                    API_PATH, sinceSeconds);

            AisTargetApiResponse response = webClient.post()
                    .uri(API_PATH)
                    .bodyValue(Map.of("sinceSeconds", String.valueOf(sinceSeconds)))
                    .retrieve()
                    .bodyToMono(AisTargetApiResponse.class)
                    .block();

            if (response != null && response.getTargetArr() != null) {
                List<AisTargetDto> targets = response.getTargetArr();
                log.info("[AisTargetDataReader] API 호출 완료: {} 건 조회", targets.size());
                return targets;
            } else {
                log.warn("[AisTargetDataReader] API 응답이 비어있습니다");
                return Collections.emptyList();
            }

        } catch (Exception e) {
            log.error("[AisTargetDataReader] API 호출 실패: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }
}
