package at.procon.eventhub.processing.model;

import java.time.OffsetDateTime;
import java.util.Objects;
import java.util.UUID;

public record UnifiedVehicleEventsRequest(
        UnifiedEventSourceFamily sourceFamily,
        UUID sessionId,
        String tenantKey,
        String vehicleSourceEntityId,
        String vin,
        String registrationNation,
        String registrationNumber,
        OffsetDateTime occurredFrom,
        OffsetDateTime occurredTo
) {
    public UnifiedVehicleEventsRequest {
        Objects.requireNonNull(sourceFamily, "sourceFamily must not be null");
        tenantKey = normalize(tenantKey);
        vehicleSourceEntityId = normalize(vehicleSourceEntityId);
        vin = normalizeUpper(vin);
        registrationNation = normalizeUpper(registrationNation);
        registrationNumber = normalize(registrationNumber);
        if (occurredFrom != null && occurredTo != null && occurredTo.isBefore(occurredFrom)) {
            throw new IllegalArgumentException("occurredTo must not be before occurredFrom");
        }
        if (sourceFamily == UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION) {
            Objects.requireNonNull(sessionId, "sessionId must not be null");
        } else if (tenantKey == null) {
            throw new IllegalArgumentException("tenantKey must not be blank");
        }
        if (!hasVehicleSelector(vehicleSourceEntityId, vin, registrationNumber)) {
            throw new IllegalArgumentException("At least one vehicle selector must be provided.");
        }
    }

    public static UnifiedVehicleEventsRequest forTachographFileSession(
            UUID sessionId,
            String vehicleSourceEntityId,
            String vin,
            String registrationNation,
            String registrationNumber,
            OffsetDateTime occurredFrom,
            OffsetDateTime occurredTo
    ) {
        return new UnifiedVehicleEventsRequest(
                UnifiedEventSourceFamily.TACHOGRAPH_FILE_SESSION,
                sessionId,
                null,
                vehicleSourceEntityId,
                vin,
                registrationNation,
                registrationNumber,
                occurredFrom,
                occurredTo
        );
    }

    public static UnifiedVehicleEventsRequest forTachographDb(
            String tenantKey,
            String vehicleSourceEntityId,
            String vin,
            String registrationNation,
            String registrationNumber,
            OffsetDateTime occurredFrom,
            OffsetDateTime occurredTo
    ) {
        return new UnifiedVehicleEventsRequest(
                UnifiedEventSourceFamily.TACHOGRAPH_DB,
                null,
                tenantKey,
                vehicleSourceEntityId,
                vin,
                registrationNation,
                registrationNumber,
                occurredFrom,
                occurredTo
        );
    }

    public static UnifiedVehicleEventsRequest forYellowFoxDb(
            String tenantKey,
            String vehicleSourceEntityId,
            String vin,
            String registrationNation,
            String registrationNumber,
            OffsetDateTime occurredFrom,
            OffsetDateTime occurredTo
    ) {
        return new UnifiedVehicleEventsRequest(
                UnifiedEventSourceFamily.YELLOWFOX_DB,
                null,
                tenantKey,
                vehicleSourceEntityId,
                vin,
                registrationNation,
                registrationNumber,
                occurredFrom,
                occurredTo
        );
    }

    public boolean hasVehicleSelector() {
        return hasVehicleSelector(vehicleSourceEntityId, vin, registrationNumber);
    }

    private static boolean hasVehicleSelector(String vehicleSourceEntityId, String vin, String registrationNumber) {
        return vehicleSourceEntityId != null || vin != null || registrationNumber != null;
    }

    private static String normalize(String value) {
        return value == null || value.isBlank() ? null : value.trim();
    }

    private static String normalizeUpper(String value) {
        return value == null || value.isBlank() ? null : value.trim().toUpperCase();
    }
}
