package at.procon.eventhub.service;

import at.procon.eventhub.dto.EventDomain;
import at.procon.eventhub.dto.EventHubEventDto;
import at.procon.eventhub.dto.EventHubPackageRequest;
import at.procon.eventhub.dto.EventLifecycle;
import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.dto.EventType;
import at.procon.eventhub.dto.GeoPointDto;
import at.procon.eventhub.dto.ImportScopeDto;
import at.procon.eventhub.dto.SourceGroupRefDto;
import at.procon.eventhub.dto.SourceGroupType;
import at.procon.eventhub.dto.source.TelematicsPositionDto;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.UUID;
import org.springframework.stereotype.Component;

@Component
public class TelematicsPositionEventMapper {

    private final EventDetailsFactory detailsFactory;

    public TelematicsPositionEventMapper(EventDetailsFactory detailsFactory) {
        this.detailsFactory = detailsFactory;
    }

    public EventHubEventDto map(TelematicsPositionDto source) {
        String provider = source.providerKey() == null || source.providerKey().isBlank() ? "TELEMATICS" : source.providerKey();
        String sourceKey = source.sourceKey() == null || source.sourceKey().isBlank() ? provider + "_POSITION" : source.sourceKey();
        EventSourceDto eventSource = new EventSourceDto(
                provider,
                "TELEMATICS_PLATFORM",
                sourceKey,
                source.sourceInstanceKey(),
                source.tenantProviderSettingKey(),
                source.externalFleetKey()
        );
        LocalDate businessDate = source.occurredAt().toLocalDate();
        var occurredFrom = businessDate.atStartOfDay(source.occurredAt().getOffset()).toOffsetDateTime();
        var occurredTo = businessDate.plusDays(1).atStartOfDay(source.occurredAt().getOffset()).toOffsetDateTime();
        SourceGroupRefDto sourceGroup = source.externalFleetKey() == null || source.externalFleetKey().isBlank()
                ? null
                : new SourceGroupRefDto(SourceGroupType.FLEET, source.externalFleetKey(), source.externalFleetKey(), null);
        EventHubPackageRequest packageInfo = new EventHubPackageRequest(
                tenantOrDefault(source.tenantKey()),
                eventSource,
                sourceGroup,
                ImportScopeDto.tenantAll(occurredFrom, occurredTo),
                EventDomain.POSITION.name(),
                businessDate,
                eventSource.stableKey() + ":POSITION:" + businessDate
        );

        return new EventHubEventDto(
                UUID.randomUUID(),
                source.externalSourceEventId(),
                source.driverRef(),
                source.vehicleRef(),
                source.occurredAt(),
                source.receivedPartnerAt(),
                OffsetDateTime.now(),
                EventDomain.POSITION,
                EventType.POSITION_RECORDED,
                EventLifecycle.SNAPSHOT,
                source.odometerM(),
                new GeoPointDto(source.latitude(), source.longitude()),
                detailsFactory.position(source.positionReason()),
                null,
                detailsFactory.payloadFromMap(source.payload()),
                false,
                packageInfo
        );
    }

    private String tenantOrDefault(String value) {
        return value == null || value.isBlank() ? "default" : value.trim();
    }
}
