package at.procon.eventhub.dto;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.time.OffsetDateTime;

/**
 * Selection scope used by acquisition jobs.
 *
 * Organisation scope and event-time scope are intentionally modeled together,
 * because a tachograph import can be unrestricted, organisation-subtree scoped,
 * time-window scoped, or both.
 */
public record ImportScopeDto(
        @NotNull ImportScopeType type,
        @Valid SourceGroupRefDto rootSourceOrganisation,
        boolean includeChildren,
        OffsetDateTime occurredFrom,
        OffsetDateTime occurredTo
) {
    public ImportScopeDto {
        if (type == null) {
            type = ImportScopeType.TENANT_ALL;
        }
        if (occurredFrom != null && occurredTo != null && !occurredFrom.isBefore(occurredTo)) {
            throw new IllegalArgumentException("importScope.occurredFrom must be before occurredTo");
        }
        if (type == ImportScopeType.SOURCE_ORGANISATION_SUBTREE) {
            if (rootSourceOrganisation == null || rootSourceOrganisation.type() != SourceGroupType.ORGANISATION) {
                throw new IllegalArgumentException("SOURCE_ORGANISATION_SUBTREE requires rootSourceOrganisation.type=ORGANISATION");
            }
        }
    }

    public static ImportScopeDto tenantAll(OffsetDateTime occurredFrom, OffsetDateTime occurredTo) {
        return new ImportScopeDto(ImportScopeType.TENANT_ALL, null, false, occurredFrom, occurredTo);
    }

    public String stableKey() {
        return type.name() + ":"
                + (rootSourceOrganisation == null ? "ALL" : rootSourceOrganisation.stableKey()) + ":"
                + (includeChildren ? "WITH_CHILDREN" : "NO_CHILDREN") + ":"
                + (occurredFrom == null ? "BEGIN" : occurredFrom.toString()) + ":"
                + (occurredTo == null ? "END" : occurredTo.toString());
    }
}
