<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Streaming\Dlq;

final class StreamDlqCollection
{
    /** @var array<string, StreamDlqMessage> */
    private array $messages = [];

    public static function fromArray(array $items): self
    {
        $collection = new self();

        foreach ($items as $item) {
            if (is_array($item)) {
                $message = StreamDlqMessage::fromArray($item);
                $collection->messages[$message->dlqId()] = $message;
            }
        }

        return $collection;
    }

    public function add(StreamDlqMessage $message): StreamDlqMessage
    {
        $this->messages[$message->dlqId()] = $message;
        return $message;
    }

    public function get(string $dlqId): ?StreamDlqMessage
    {
        return $this->messages[$dlqId] ?? null;
    }

    public function put(StreamDlqMessage $message): void
    {
        $this->messages[$message->dlqId()] = $message;
    }

    public function all(): array
    {
        return array_values($this->messages);
    }

    public function active(): array
    {
        return array_values(array_filter($this->messages, static fn (StreamDlqMessage $m): bool => !in_array($m->status(), [StreamDlqStatus::RETRIED, StreamDlqStatus::REPLAYED, StreamDlqStatus::CLEARED], true)));
    }

    public function count(): int
    {
        return count($this->messages);
    }

    public function clear(): int
    {
        $cleared = 0;
        foreach ($this->messages as $id => $message) {
            if ($message->status() !== StreamDlqStatus::CLEARED) {
                $this->messages[$id] = $message->markCleared();
                $cleared++;
            }
        }
        return $cleared;
    }

    public function toArray(): array
    {
        return array_map(static fn (StreamDlqMessage $message): array => $message->toArray(), $this->all());
    }
}
