package gc.mda.signal_batch.batch.processor;

import gc.mda.signal_batch.domain.vessel.dto.AisTargetDto;
import gc.mda.signal_batch.domain.vessel.model.AisTargetEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.stereotype.Component;

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

/**
 * AIS Target DTO → Entity 변환 Processor
 *
 * - 타임스탬프 파싱 (ISO 8601)
 * - 유효성 필터링 (MMSI, Lat, Lon 필수)
 * - gc-signal-batch에서는 mmsi를 String으로 처리
 */
@Slf4j
@Component
public class AisTargetDataProcessor implements ItemProcessor<AisTargetDto, AisTargetEntity> {

    private static final DateTimeFormatter ISO_FORMATTER = DateTimeFormatter.ISO_DATE_TIME;

    @Override
    public AisTargetEntity process(AisTargetDto dto) {
        // 유효성 검사: MMSI와 위치 정보 필수
        if (dto.getMmsi() == null || dto.getMmsi().isBlank()
                || dto.getLat() == null || dto.getLon() == null) {
            log.debug("유효하지 않은 데이터 스킵 - MMSI: {}, Lat: {}, Lon: {}",
                    dto.getMmsi(), dto.getLat(), dto.getLon());
            return null;
        }

        // MessageTimestamp 파싱
        OffsetDateTime messageTimestamp = parseTimestamp(dto.getMessageTimestamp());
        if (messageTimestamp == null) {
            log.debug("MessageTimestamp 파싱 실패 - MMSI: {}, Timestamp: {}",
                    dto.getMmsi(), dto.getMessageTimestamp());
            return null;
        }

        return AisTargetEntity.builder()
                .mmsi(dto.getMmsi())
                .imo(dto.getImo())
                .name(dto.getName())
                .callsign(dto.getCallsign())
                .vesselType(dto.getVesselType())
                .extraInfo(dto.getExtraInfo())
                .lat(dto.getLat())
                .lon(dto.getLon())
                .heading(dto.getHeading())
                .sog(dto.getSog())
                .cog(dto.getCog())
                .rot(dto.getRot())
                .length(dto.getLength())
                .width(dto.getWidth())
                .draught(dto.getDraught())
                .destination(dto.getDestination())
                .eta(parseEta(dto.getEta()))
                .status(dto.getStatus())
                .messageTimestamp(messageTimestamp)
                .build();
    }

    private OffsetDateTime parseTimestamp(String timestamp) {
        if (timestamp == null || timestamp.isEmpty()) {
            return null;
        }
        try {
            return OffsetDateTime.parse(timestamp, ISO_FORMATTER);
        } catch (DateTimeParseException e) {
            log.trace("타임스탬프 파싱 실패: {}", timestamp);
            return null;
        }
    }

    private OffsetDateTime parseEta(String eta) {
        if (eta == null || eta.isEmpty() || "9999-12-31T23:59:59Z".equals(eta)) {
            return null;
        }
        return parseTimestamp(eta);
    }
}
