<?php
declare(strict_types=1);

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

final class WorkerStaleRecord
{
    public const HEALTHY = 'healthy';
    public const STALE = 'stale';
    public const HUNG = 'hung';
    public const OFFLINE = 'offline';
    public const FAILED = 'failed';

    public function __construct(
        private readonly string $workerId,
        private readonly string $classification,
        private readonly string $reason = '',
        private readonly int $ageSeconds = 0,
        private readonly array $heartbeat = [],
        private readonly string $detectedAt = ''
    ) {}

    public static function healthy(string $workerId, int $ageSeconds, array $heartbeat = []): self
    {
        return new self($workerId, self::HEALTHY, 'heartbeat current', $ageSeconds, $heartbeat, date('c'));
    }

    public static function stale(string $workerId, int $ageSeconds, array $heartbeat = []): self
    {
        return new self($workerId, self::STALE, 'heartbeat timeout exceeded', $ageSeconds, $heartbeat, date('c'));
    }

    public static function hung(string $workerId, int $ageSeconds, array $heartbeat = []): self
    {
        return new self($workerId, self::HUNG, 'running timeout exceeded', $ageSeconds, $heartbeat, date('c'));
    }

    public static function offline(string $workerId): self
    {
        return new self($workerId, self::OFFLINE, 'missing heartbeat', 0, [], date('c'));
    }

    public static function failed(string $workerId, int $ageSeconds, array $heartbeat = []): self
    {
        return new self($workerId, self::FAILED, 'worker failure recorded', $ageSeconds, $heartbeat, date('c'));
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['workerId'] ?? ''),
            (string) ($data['classification'] ?? self::HEALTHY),
            (string) ($data['reason'] ?? ''),
            (int) ($data['ageSeconds'] ?? 0),
            (array) ($data['heartbeat'] ?? []),
            (string) ($data['detectedAt'] ?? '')
        );
    }

    public function workerId(): string { return $this->workerId; }
    public function classification(): string { return $this->classification; }
    public function isStale(): bool { return in_array($this->classification, [self::STALE, self::HUNG, self::OFFLINE, self::FAILED], true); }

    public function toArray(): array
    {
        return [
            'workerId' => $this->workerId,
            'classification' => $this->classification,
            'stale' => $this->isStale(),
            'reason' => $this->reason,
            'ageSeconds' => $this->ageSeconds,
            'heartbeat' => $this->heartbeat,
            'detectedAt' => $this->detectedAt !== '' ? $this->detectedAt : date('c'),
        ];
    }
}
