package at.procon.eventhub.dto;

import jakarta.validation.Valid;

/**
 * Source-side vehicle reference. A physical tachograph vehicle is identified by
 * VehicleIdentification.ID/VIN. A registration/plate is identified separately by
 * Vehicle.ID/VRN because plates can move between vehicles over time.
 *
 * Organisation assignment is intentionally not stored on the event. Vehicle and
 * registration relations belong to master data and can be resolved historically.
 */
public record VehicleRefDto(
        String sourceVehicleEntityId,
        String vin,
        String sourceRegistrationEntityId,
        @Valid at.procon.eventhub.dto.VehicleRegistrationRefDto vehicleRegistration
) {
    public VehicleRefDto(
            String sourceEntityId,
            String vin,
            at.procon.eventhub.dto.VehicleRegistrationRefDto vehicleRegistration
    ) {
        this(sourceEntityId, vin, null, vehicleRegistration);
    }

    public VehicleRefDto {
        sourceVehicleEntityId = normalizeNullable(sourceVehicleEntityId);
        vin = normalizeVin(vin);
        sourceRegistrationEntityId = normalizeNullable(sourceRegistrationEntityId);
    }

    public boolean hasAnyReference() {
        return (sourceVehicleEntityId != null && !sourceVehicleEntityId.isBlank())
                || (vin != null && !vin.isBlank())
                || (sourceRegistrationEntityId != null && !sourceRegistrationEntityId.isBlank())
                || (vehicleRegistration != null && vehicleRegistration.hasValue());
    }

    public String stableKey() {
        String registrationKey = vehicleRegistration == null ? "" : vehicleRegistration.stableKey();
        return (sourceVehicleEntityId == null ? "" : sourceVehicleEntityId) + "|"
                + (vin == null ? "" : vin) + "|"
                + (sourceRegistrationEntityId == null ? "" : sourceRegistrationEntityId) + "|"
                + registrationKey;
    }

    /**
     * Backward-compatible accessor for older code paths that treated vehicle and
     * registration source IDs as one field.
     */
    public String sourceEntityId() {
        return sourceVehicleEntityId != null ? sourceVehicleEntityId : sourceRegistrationEntityId;
    }

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

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