package at.procon.eventhub.processing.service;

import at.procon.eventhub.dto.EventHubEventDto;
import at.procon.eventhub.processing.model.UnifiedDiscoveredVehicleRef;
import at.procon.eventhub.processing.model.UnifiedDriverEventsRequest;
import at.procon.eventhub.processing.model.UnifiedEventSourceFamily;
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBackend;
import at.procon.eventhub.processing.model.UnifiedRuntimeProcessingRequest;
import at.procon.eventhub.processing.model.UnifiedVehicleEventsRequest;
import java.util.List;
import org.springframework.stereotype.Component;

@Component
public class EventHubRuntimeEventLoader implements RuntimeDriverEventLoader, RuntimeVehicleEventLoader {

    private final UnifiedDriverEventSourceService driverEventSourceService;
    private final UnifiedVehicleEventSourceService vehicleEventSourceService;

    public EventHubRuntimeEventLoader(
            UnifiedDriverEventSourceService driverEventSourceService,
            UnifiedVehicleEventSourceService vehicleEventSourceService
    ) {
        this.driverEventSourceService = driverEventSourceService;
        this.vehicleEventSourceService = vehicleEventSourceService;
    }

    @Override
    public boolean supports(UnifiedRuntimeProcessingRequest request, UnifiedEventSourceFamily sourceFamily) {
        return request.eventBackend() == UnifiedRuntimeEventBackend.EVENTHUB_DB
                && (sourceFamily == UnifiedEventSourceFamily.TACHOGRAPH_DB
                || sourceFamily == UnifiedEventSourceFamily.YELLOWFOX_DB);
    }

    @Override
    public List<EventHubEventDto> loadDriverEvents(UnifiedRuntimeProcessingRequest request) {
        throw new UnsupportedOperationException("Source family must be specified when loading EventHub-backed runtime driver events.");
    }

    @Override
    public List<EventHubEventDto> loadVehicleEvents(
            UnifiedRuntimeProcessingRequest request,
            UnifiedDiscoveredVehicleRef vehicleRef
    ) {
        throw new UnsupportedOperationException("Source family must be specified when loading EventHub-backed runtime vehicle events.");
    }

    public List<EventHubEventDto> loadDriverEvents(
            UnifiedRuntimeProcessingRequest request,
            UnifiedEventSourceFamily sourceFamily
    ) {
        return driverEventSourceService.loadDriverEvents(driverRequest(request, sourceFamily));
    }

    public List<EventHubEventDto> loadVehicleEvents(
            UnifiedRuntimeProcessingRequest request,
            UnifiedEventSourceFamily sourceFamily,
            UnifiedDiscoveredVehicleRef vehicleRef
    ) {
        return vehicleEventSourceService.loadVehicleEvents(vehicleRequest(request, sourceFamily, vehicleRef));
    }

    private UnifiedDriverEventsRequest driverRequest(
            UnifiedRuntimeProcessingRequest request,
            UnifiedEventSourceFamily sourceFamily
    ) {
        return switch (sourceFamily) {
            case TACHOGRAPH_DB -> UnifiedDriverEventsRequest.forTachographDbDriver(
                    request.tenantKey(),
                    request.driverSourceEntityId(),
                    request.driverCardNation(),
                    request.driverCardNumber(),
                    request.occurredFrom(),
                    request.occurredTo()
            );
            case YELLOWFOX_DB -> UnifiedDriverEventsRequest.forYellowFoxDbDriver(
                    request.tenantKey(),
                    request.driverSourceEntityId(),
                    request.driverCardNation(),
                    request.driverCardNumber(),
                    request.occurredFrom(),
                    request.occurredTo()
            );
            default -> throw new IllegalArgumentException("EventHub runtime backend does not support source family " + sourceFamily + ".");
        };
    }

    private UnifiedVehicleEventsRequest vehicleRequest(
            UnifiedRuntimeProcessingRequest request,
            UnifiedEventSourceFamily sourceFamily,
            UnifiedDiscoveredVehicleRef vehicleRef
    ) {
        return switch (sourceFamily) {
            case TACHOGRAPH_DB -> UnifiedVehicleEventsRequest.forTachographDb(
                    request.tenantKey(),
                    vehicleRef.sourceVehicleEntityId(),
                    vehicleRef.vin(),
                    vehicleRef.registrationNation(),
                    vehicleRef.registrationNumber(),
                    request.vehicleOccurredFrom(),
                    request.vehicleOccurredTo()
            );
            case YELLOWFOX_DB -> UnifiedVehicleEventsRequest.forYellowFoxDb(
                    request.tenantKey(),
                    vehicleRef.sourceVehicleEntityId(),
                    vehicleRef.vin(),
                    vehicleRef.registrationNation(),
                    vehicleRef.registrationNumber(),
                    request.vehicleOccurredFrom(),
                    request.vehicleOccurredTo()
            );
            default -> throw new IllegalArgumentException("EventHub runtime backend does not support source family " + sourceFamily + ".");
        };
    }
}
