package de.assecutor.votianlt.messaging.delivery;

import de.assecutor.votianlt.messaging.model.*;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;

/**
 * Service for reliable message delivery with acknowledgment tracking.
 * Provides guaranteed delivery with retry mechanism and acknowledgment handling.
 */
public interface MessageDeliveryService {

    /**
     * Send a message to a specific client with delivery tracking and acknowledgment.
     *
     * @param clientId    The target client identifier
     * @param messageType The type of message (e.g., "jobs", "message", "auth", "task")
     * @param payload     The message payload (will be serialized to JSON)
     * @param options     Delivery options (retries, timeout, etc.)
     * @return CompletableFuture with delivery receipt
     */
    CompletableFuture<DeliveryReceipt> sendToClient(String clientId, String messageType, Object payload, DeliveryOptions options);

    /**
     * Send a message to a specific client with default delivery options.
     *
     * @param clientId    The target client identifier
     * @param messageType The type of message
     * @param payload     The message payload
     * @return CompletableFuture with delivery receipt
     */
    default CompletableFuture<DeliveryReceipt> sendToClient(String clientId, String messageType, Object payload) {
        return sendToClient(clientId, messageType, payload, DeliveryOptions.standard());
    }

    /**
     * Send a message with delivery tracking and acknowledgment.
     * @deprecated Use {@link #sendToClient(String, String, Object, DeliveryOptions)} instead
     *
     * @param topic   The destination topic
     * @param payload The message payload (will be serialized to JSON)
     * @param options Delivery options (retries, timeout, etc.)
     * @return CompletableFuture with delivery receipt
     */
    @Deprecated
    CompletableFuture<DeliveryReceipt> sendMessage(String topic, Object payload, DeliveryOptions options);

    /**
     * Send a message with default delivery options.
     * @deprecated Use {@link #sendToClient(String, String, Object)} instead
     *
     * @param topic   The destination topic
     * @param payload The message payload
     * @return CompletableFuture with delivery receipt
     */
    @Deprecated
    default CompletableFuture<DeliveryReceipt> sendMessage(String topic, Object payload) {
        return sendMessage(topic, payload, DeliveryOptions.standard());
    }

    /**
     * Handle incoming message envelope from transport layer.
     * Extracts payload and routes to application layer.
     *
     * @param envelope The received message envelope
     */
    void handleIncomingMessage(MessageEnvelope envelope);

    /**
     * Handle acknowledgment from client.
     * Updates delivery status and removes from pending queue.
     *
     * @param ack The acknowledgment message
     */
    void handleAcknowledgment(AcknowledgmentMessage ack);

    /**
     * Get the current delivery status for a message.
     *
     * @param messageId The message ID
     * @return Optional containing the delivery status, or empty if not found
     */
    Optional<DeliveryStatus> getDeliveryStatus(String messageId);

    /**
     * Get detailed pending delivery information.
     *
     * @param messageId The message ID
     * @return Optional containing the pending delivery, or empty if not found
     */
    Optional<PendingDelivery> getPendingDelivery(String messageId);

    /**
     * Retry all pending deliveries that are ready for retry.
     * Called by scheduled task.
     */
    void retryPendingDeliveries();

    /**
     * Retry pending deliveries for a specific client.
     * Called when a client reconnects.
     *
     * @param clientId The client identifier
     */
    void retryPendingDeliveriesForClient(String clientId);

    /**
     * Clean up expired and completed deliveries.
     * Called by scheduled task.
     */
    void cleanupOldDeliveries();
}

