<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Worker\Monitoring;

final class WorkerHealthStatus
{
    public const HEALTHY = 'healthy';
    public const IDLE = 'idle';
    public const BUSY = 'busy';
    public const DEGRADED = 'degraded';
    public const STALLED = 'stalled';
    public const OFFLINE = 'offline';
    public const FAILED = 'failed';

    public function __construct(
        private readonly string $state = self::HEALTHY,
        private readonly string $reason = '',
        private readonly string $checkedAt = ''
    ) {}

    public static function fromHeartbeat(WorkerHeartbeat $heartbeat, int $staleAfterSeconds = 60): self
    {
        $age = time() - strtotime($heartbeat->recordedAt());

        if ($age > $staleAfterSeconds) {
            return new self(self::OFFLINE, 'heartbeat stale', date('c'));
        }

        if ($heartbeat->status() === 'failed' || $heartbeat->failed() > 0) {
            return new self(self::FAILED, 'worker failure recorded', date('c'));
        }

        if ($heartbeat->status() === 'running') {
            return new self(self::BUSY, 'worker running', date('c'));
        }

        if ($heartbeat->status() === 'idle') {
            return new self(self::IDLE, 'worker idle', date('c'));
        }

        return new self(self::HEALTHY, 'worker healthy', date('c'));
    }

    public function state(): string { return $this->state; }
    public function reason(): string { return $this->reason; }
    public function checkedAt(): string { return $this->checkedAt !== '' ? $this->checkedAt : date('c'); }

    public function healthy(): bool
    {
        return in_array($this->state, [self::HEALTHY, self::IDLE, self::BUSY], true);
    }

    public function toArray(): array
    {
        return [
            'state' => $this->state,
            'reason' => $this->reason,
            'healthy' => $this->healthy(),
            'checkedAt' => $this->checkedAt(),
        ];
    }
}
