package at.procon.eventhub.esperpoc.dto;

import java.time.Duration;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.UUID;

public record OperatingPeriodActivityIntervalDto(
        UUID driverId,
        UUID vehicleId,
        UUID vehicleRegistrationId,
        String activityType,
        String cardSlot,
        String cardStatus,
        String drivingStatus,
        String sourceKind,
        OffsetDateTime startedAt,
        OffsetDateTime endedAt,
        long durationSeconds,
        String sourceRowId,
        List<String> sourceRowIds,
        boolean clippedToRequestedPeriod,
        String level,
        long operatingPeriodNo,
        OffsetDateTime operatingPeriodStartedAt,
        boolean newOperatingPeriod,
        Long gapSincePreviousActivitySeconds,
        boolean synthetic
) {
    public static OperatingPeriodActivityIntervalDto periodized(
            ActivityIntervalDto interval,
            long operatingPeriodNo,
            OffsetDateTime operatingPeriodStartedAt,
            boolean newOperatingPeriod,
            Long gapSincePreviousActivitySeconds
    ) {
        return new OperatingPeriodActivityIntervalDto(
                interval.driverEntityId(),
                interval.vehicleId(),
                interval.vehicleRegistrationId(),
                interval.activityType(),
                interval.cardSlot(),
                interval.cardStatus(),
                interval.drivingStatus(),
                interval.sourceKind(),
                interval.startedAt(),
                interval.endedAt(),
                interval.durationSeconds(),
                interval.sourceRowId(),
                interval.sourceRowIds(),
                interval.clippedToRequestedPeriod(),
                "PERIODIZED_ACTIVITY",
                operatingPeriodNo,
                operatingPeriodStartedAt,
                newOperatingPeriod,
                gapSincePreviousActivitySeconds,
                "UNKNOWN_GAP".equals(interval.level())
        );
    }

    public OperatingPeriodActivityIntervalDto withTime(OffsetDateTime newStartedAt, OffsetDateTime newEndedAt, boolean clipped) {
        return new OperatingPeriodActivityIntervalDto(
                driverId,
                vehicleId,
                vehicleRegistrationId,
                activityType,
                cardSlot,
                cardStatus,
                drivingStatus,
                sourceKind,
                newStartedAt,
                newEndedAt,
                Duration.between(newStartedAt, newEndedAt).getSeconds(),
                sourceRowId,
                sourceRowIds,
                clipped,
                level,
                operatingPeriodNo,
                operatingPeriodStartedAt,
                newOperatingPeriod,
                gapSincePreviousActivitySeconds,
                synthetic
        );
    }

    public OperatingPeriodActivityIntervalDto asMerged(OffsetDateTime newEndedAt, List<String> mergedSourceRowIds) {
        return new OperatingPeriodActivityIntervalDto(
                driverId,
                vehicleId,
                vehicleRegistrationId,
                activityType,
                cardSlot,
                cardStatus,
                drivingStatus,
                sourceKind,
                startedAt,
                newEndedAt,
                Duration.between(startedAt, newEndedAt).getSeconds(),
                sourceRowId,
                mergedSourceRowIds,
                clippedToRequestedPeriod,
                "MERGED_ACTIVITY",
                operatingPeriodNo,
                operatingPeriodStartedAt,
                newOperatingPeriod,
                gapSincePreviousActivitySeconds,
                synthetic
        );
    }
}
