package de.assecutor.votianlt.messaging.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * Options for message delivery configuration.
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DeliveryOptions {

    /**
     * Whether this message requires acknowledgment
     */
    @Builder.Default
    private boolean requiresAck = true;

    /**
     * Maximum number of retry attempts
     */
    @Builder.Default
    private int maxRetries = 3;

    /**
     * Timeout for acknowledgment
     */
    @Builder.Default
    private Duration ackTimeout = Duration.ofSeconds(30);

    /**
     * Message expiry duration from now
     */
    @Builder.Default
    private Duration expiryDuration = Duration.ofHours(24);

    /**
     * QoS level for transport (MQTT specific, but kept generic)
     */
    @Builder.Default
    private int qos = 2;

    /**
     * Whether message should be retained by broker
     */
    @Builder.Default
    private boolean retained = false;

    /**
     * Calculate expiry timestamp from duration
     */
    public LocalDateTime calculateExpiryTime() {
        return LocalDateTime.now().plus(expiryDuration);
    }

    /**
     * Default options for standard messages
     */
    public static DeliveryOptions standard() {
        return DeliveryOptions.builder().build();
    }

    /**
     * Options for fire-and-forget messages (no acknowledgment required)
     */
    public static DeliveryOptions fireAndForget() {
        return DeliveryOptions.builder()
                .requiresAck(false)
                .maxRetries(0)
                .build();
    }

    /**
     * Options for critical messages with extended retry
     */
    public static DeliveryOptions critical() {
        return DeliveryOptions.builder()
                .requiresAck(true)
                .maxRetries(5)
                .ackTimeout(Duration.ofMinutes(2))
                .expiryDuration(Duration.ofDays(7))
                .build();
    }
}

