package at.procon.eventhub.processing.service;

import at.procon.eventhub.dto.EventHubEventDto;
import at.procon.eventhub.processing.model.UnifiedDriverEventsRequest;
import at.procon.eventhub.processing.model.UnifiedEventSourceFamily;
import at.procon.eventhub.tachographfilesession.model.DriverExtractionSession;
import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
import at.procon.eventhub.tachographfilesession.service.DriverNotFoundInSessionException;
import at.procon.eventhub.tachographfilesession.service.DriverTimelineEventBuilder;
import at.procon.eventhub.tachographfilesession.service.TachographFileSessionNotFoundException;
import at.procon.eventhub.tachographfilesession.service.TachographFileSessionRepository;
import java.time.OffsetDateTime;
import java.util.List;
import org.springframework.stereotype.Component;

@Component
public class TachographFileSessionUnifiedDriverEventSource implements UnifiedDriverEventSource {

    private final TachographFileSessionRepository repository;
    private final DriverTimelineEventBuilder eventBuilder;

    public TachographFileSessionUnifiedDriverEventSource(
            TachographFileSessionRepository repository,
            DriverTimelineEventBuilder eventBuilder
    ) {
        this.repository = repository;
        this.eventBuilder = eventBuilder;
    }

    @Override
    public boolean supports(UnifiedDriverEventsRequest request) {
        return request.sourceFamily() == UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION;
    }

    @Override
    public List<EventHubEventDto> loadDriverEvents(UnifiedDriverEventsRequest request) {
        TachographFileSession session = repository.find(request.sessionId())
                .orElseThrow(() -> new TachographFileSessionNotFoundException(request.sessionId()));
        DriverExtractionSession driver = session.driversByKey().get(request.driverKey());
        if (driver == null) {
            throw new DriverNotFoundInSessionException(request.sessionId(), request.driverKey());
        }
        return eventBuilder.buildEvents(session, driver).stream()
                .filter(event -> withinWindow(event.occurredAt(), request.occurredFrom(), request.occurredTo()))
                .toList();
    }

    private boolean withinWindow(
            OffsetDateTime occurredAt,
            OffsetDateTime occurredFrom,
            OffsetDateTime occurredTo
    ) {
        if (occurredAt == null) {
            return false;
        }
        if (occurredFrom != null && occurredAt.isBefore(occurredFrom)) {
            return false;
        }
        return occurredTo == null || !occurredAt.isAfter(occurredTo);
    }
}
