package at.procon.eventhub.tachographfilesession.service;

import static org.assertj.core.api.Assertions.assertThat;

import at.procon.eventhub.service.EventDetailsFactory;
import at.procon.eventhub.tachographfilesession.model.DriverExtractionSession;
import at.procon.eventhub.tachographfilesession.model.ExtractedCardActivityInterval;
import at.procon.eventhub.tachographfilesession.model.ExtractedCardVehicleUsageInterval;
import at.procon.eventhub.tachographfilesession.model.ExtractedDriver;
import at.procon.eventhub.tachographfilesession.model.ExtractedDriverCard;
import at.procon.eventhub.tachographfilesession.model.ExtractedSupportEvent;
import at.procon.eventhub.tachographfilesession.model.ExtractedVehicle;
import at.procon.eventhub.tachographfilesession.model.ExtractedVehicleRegistration;
import at.procon.eventhub.tachographfilesession.model.ExtractionStats;
import at.procon.eventhub.tachographfilesession.model.ResolvedDriverTimeline;
import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
import at.procon.eventhub.tachographfilesession.model.TachographFileSessionMetadata;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;

class EventBackedDriverTimelineBuilderTest {

    private final DriverTimelineBuilder directBuilder = new DriverTimelineBuilder();
    private final EventBackedDriverTimelineBuilder eventBackedBuilder =
            new EventBackedDriverTimelineBuilder(
                    new IntervalBackedDriverTimelineEventBuilder(
                            directBuilder,
                            new DriverKeyFactory(),
                            new VehicleKeyFactory(),
                            new EventDetailsFactory(new ObjectMapper())
                    )
            );

    @Test
    void reconstructsTimelineFromEvents() {
        DriverExtractionSession driver = new DriverExtractionSession(
                "12:123",
                new ExtractedDriver("12:123", "DRV:12:123", "Doe", "Jane", null, null, null, null, null),
                new ExtractedDriverCard("CARD:12:123", "12", "123", null, null, null, null),
                List.of(new ExtractedVehicleRegistration("12:REG-1", "VR:12:REG-1", "12", "REG-1")),
                List.of(new ExtractedVehicle("VIN-1", "VIN:VIN-1", "VIN-1")),
                List.of(new ExtractedCardVehicleUsageInterval(
                        "CVU-1",
                        OffsetDateTime.parse("2026-05-01T08:00:00Z"),
                        OffsetDateTime.parse("2026-05-01T10:00:00Z"),
                        100L,
                        200L,
                        "12:REG-1",
                        "VIN-1",
                        "vu-1"
                )),
                List.of(new ExtractedCardActivityInterval(
                        "ACT-1",
                        OffsetDateTime.parse("2026-05-01T08:30:00Z"),
                        OffsetDateTime.parse("2026-05-01T09:00:00Z"),
                        "DRIVE",
                        "DRIVER",
                        "INSERTED",
                        "SINGLE",
                        "12:REG-1",
                        "VIN-1",
                        "a"
                )),
                List.of(new ExtractedSupportEvent(
                        "SUP-1",
                        OffsetDateTime.parse("2026-05-01T08:45:00Z"),
                        "POSITION",
                        "POSITION_RECORDED",
                        "SNAPSHOT",
                        "DRIVER",
                        "12:REG-1",
                        "VIN-1",
                        null,
                        null,
                        null,
                        null,
                        null,
                        BigDecimal.valueOf(48.2082),
                        BigDecimal.valueOf(16.3738),
                        "AUTHENTIC",
                        150L,
                        null,
                        null,
                        null,
                        "raw-path"
                )),
                List.of()
        );
        TachographFileSession session = new TachographFileSession(
                UUID.randomUUID(),
                new TachographFileSessionMetadata("default", "legalrequirements-drivercard", "sample", "sample.ddd", "a", 2, "42", "b", true, null),
                Map.of(driver.driverKey(), driver),
                new ExtractionStats(1, 1, 1, 1, 1, 0),
                List.of(),
                Instant.now(),
                Instant.now().plus(4, ChronoUnit.HOURS)
        );

        ResolvedDriverTimeline direct = directBuilder.build(session, driver);
        ResolvedDriverTimeline reconstructed = eventBackedBuilder.build(session, driver);

        assertThat(reconstructed.sourceKind()).isEqualTo(direct.sourceKind());
        assertThat(reconstructed.loadedFrom()).isEqualTo(direct.loadedFrom());
        assertThat(reconstructed.loadedTo()).isEqualTo(direct.loadedTo());
        assertThat(reconstructed.activityIntervals()).containsExactlyElementsOf(direct.activityIntervals());
        assertThat(reconstructed.vehicleUsageIntervals()).containsExactlyElementsOf(direct.vehicleUsageIntervals());
        assertThat(reconstructed.supportEvents()).containsExactlyElementsOf(direct.supportEvents());
    }
}
