<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Dispatcher;

final class DispatcherStatistics
{
    public function __construct(
        private readonly int $queued = 0,
        private readonly int $executed = 0,
        private readonly int $completed = 0,
        private readonly int $retried = 0,
        private readonly int $deadLettered = 0,
        private readonly int $failed = 0,
        private readonly float $executionTimeMs = 0.0
    ) {}

    public function queued(): int { return $this->queued; }
    public function executed(): int { return $this->executed; }
    public function completed(): int { return $this->completed; }
    public function retried(): int { return $this->retried; }
    public function deadLettered(): int { return $this->deadLettered; }
    public function failed(): int { return $this->failed; }

    public function withQueued(int $queued): self
    {
        return new self($queued, $this->executed, $this->completed, $this->retried, $this->deadLettered, $this->failed, $this->executionTimeMs);
    }

    public function record(DispatcherResult $result, float $timeMs): self
    {
        return new self(
            $this->queued,
            $this->executed + 1,
            $this->completed + ($result->ok() ? 1 : 0),
            $this->retried + ($result->retried() ? 1 : 0),
            $this->deadLettered + ($result->deadLettered() ? 1 : 0),
            $this->failed + (!$result->ok() ? 1 : 0),
            $this->executionTimeMs + $timeMs
        );
    }

    public function toArray(): array
    {
        return [
            'queued' => $this->queued,
            'executed' => $this->executed,
            'completed' => $this->completed,
            'retried' => $this->retried,
            'deadLettered' => $this->deadLettered,
            'failed' => $this->failed,
            'executionTimeMs' => round($this->executionTimeMs, 3),
            'averageExecutionTimeMs' => $this->executed > 0 ? round($this->executionTimeMs / $this->executed, 3) : 0,
        ];
    }
}
