package gc.mda.kcg.collector.sensor;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import gc.mda.kcg.collector.CollectorStatusTracker;
import gc.mda.kcg.domain.sensor.SeismicEvent;
import gc.mda.kcg.domain.sensor.SeismicEventRepository;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.time.Instant;

@Slf4j
@Component
@RequiredArgsConstructor
public class SeismicCollector {

    private static final String USGS_URL =
        "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson" +
        "&minlatitude=25&maxlatitude=40&minlongitude=44&maxlongitude=63" +
        "&orderby=time&limit=50&minmagnitude=2";

    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    private final SeismicEventRepository repository;
    private final CollectorStatusTracker tracker;

    @PostConstruct
    public void init() {
        Thread.ofVirtual().name("seismic-init").start(() -> {
            log.info("USGS 지진 데이터 초기 로드");
            collect();
        });
    }

    @Scheduled(initialDelay = 60_000, fixedDelay = 300_000)
    public void collectScheduled() {
        collect();
    }

    private void collect() {
        try {
            String body = restTemplate.getForObject(USGS_URL, String.class);
            if (body == null || body.isBlank()) return;

            JsonNode root = objectMapper.readTree(body);
            JsonNode features = root.path("features");
            if (!features.isArray()) return;

            int saved = 0;
            Instant now = Instant.now();
            for (JsonNode f : features) {
                JsonNode props = f.path("properties");
                JsonNode coords = f.path("geometry").path("coordinates");

                String usgsId = f.path("id").asText(null);
                if (usgsId == null) continue;
                if (repository.existsByUsgsId(usgsId)) continue;

                double mag = props.path("mag").asDouble(0);
                String place = props.path("place").asText(null);
                long timeMs = props.path("time").asLong(0);
                double lng = coords.get(0).asDouble();
                double lat = coords.get(1).asDouble();
                Double depth = coords.has(2) ? coords.get(2).asDouble() : null;

                repository.save(SeismicEvent.builder()
                        .usgsId(usgsId)
                        .magnitude(mag)
                        .depth(depth)
                        .lat(lat)
                        .lng(lng)
                        .place(place)
                        .eventTime(Instant.ofEpochMilli(timeMs))
                        .collectedAt(now)
                        .build());
                saved++;
            }
            tracker.recordSuccess("seismic", "iran", saved);
            log.debug("USGS 지진 수집 완료: {}건 저장", saved);
        } catch (Exception e) {
            tracker.recordFailure("seismic", "iran", e.getMessage());
            log.warn("USGS 지진 수집 실패: {}", e.getMessage());
        }
    }
}
