<?php
declare(strict_types=1);

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

final class WorkerHeartbeat
{
    public function __construct(
        private readonly string $workerId,
        private readonly string $status = 'idle',
        private readonly int $handled = 0,
        private readonly int $failed = 0,
        private readonly string $lastEvent = '',
        private readonly int $pid = 0,
        private readonly float $memory = 0.0,
        private readonly string $recordedAt = ''
    ) {}

    public static function record(
        string $workerId,
        string $status = 'idle',
        int $handled = 0,
        int $failed = 0,
        string $lastEvent = ''
    ): self {
        return new self(
            $workerId,
            $status,
            $handled,
            $failed,
            $lastEvent,
            function_exists('getmypid') ? (int) getmypid() : 0,
            (float) memory_get_usage(true),
            date('c')
        );
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['workerId'] ?? ''),
            (string) ($data['status'] ?? 'idle'),
            (int) ($data['handled'] ?? 0),
            (int) ($data['failed'] ?? 0),
            (string) ($data['lastEvent'] ?? ''),
            (int) ($data['pid'] ?? 0),
            (float) ($data['memory'] ?? 0),
            (string) ($data['recordedAt'] ?? '')
        );
    }

    public function workerId(): string { return $this->workerId; }
    public function status(): string { return $this->status; }
    public function handled(): int { return $this->handled; }
    public function failed(): int { return $this->failed; }
    public function lastEvent(): string { return $this->lastEvent; }
    public function recordedAt(): string { return $this->recordedAt !== '' ? $this->recordedAt : date('c'); }

    public function toArray(): array
    {
        return [
            'workerId' => $this->workerId,
            'status' => $this->status,
            'handled' => $this->handled,
            'failed' => $this->failed,
            'lastEvent' => $this->lastEvent,
            'pid' => $this->pid,
            'memory' => $this->memory,
            'recordedAt' => $this->recordedAt(),
        ];
    }
}
