<?php

declare(strict_types=1);

namespace PhpWA\Storage;

interface AccountTransactionInterface
{
    public function get(string $collection, string $key): ?StoredValue;

    /** @return array<string,StoredValue> keyed by the original state key */
    public function list(string $collection, int $limit = 1000): array;

    /** null means unconditional; 0 means the key must not exist. */
    public function put(string $collection, string $key, string $value, ?int $expectedRevision = null): StoredValue;

    /** null means unconditional; 0 means the key must not exist. */
    public function delete(string $collection, string $key, ?int $expectedRevision = null): void;

    public function hasIncoming(string $messageId): bool;

    /**
     * Atomically stages deduplication and an application event. Returns false
     * when the incoming message was committed by an earlier run.
     */
    public function stageIncoming(string $messageId, string $eventType, string $jsonPayload, int $receivedAt): bool;

    /** @return list<OutboxEvent> */
    public function claimOutbox(string $leaseOwner, int $limit, int $now, int $leaseSeconds): array;

    public function completeOutbox(string $eventId, string $leaseOwner): void;

    public function releaseOutbox(string $eventId, string $leaseOwner, int $availableAt): void;

    /** True while at least one durable application event is not completed. */
    public function hasPendingOutbox(): bool;

    public function registerRetry(string $messageId, int $now, int $maximumAttempts = 5, int $baseDelaySeconds = 2): RetryDecision;

    public function clearRetry(string $messageId): void;

    /** Removes old dedupe and completed retry metadata. */
    public function prune(int $dedupeBefore, int $retryBefore): void;
}
