<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Distributed\Scheduler;

final class DistributedScheduleAssignment
{
    public function __construct(
        private readonly string $assignmentId,
        private readonly string $jobId,
        private readonly string $queueName,
        private readonly string $nodeId,
        private readonly string $workerId,
        private readonly string $leaseId = '',
        private readonly bool $assigned = false,
        private readonly string $reason = '',
        private readonly string $assignedAt = ''
    ) {}

    public static function assigned(DistributedScheduleJob $job, array $worker, string $leaseId): self
    {
        return new self(
            'assignment_' . substr(hash('sha256', $job->jobId() . $leaseId . microtime(true)), 0, 20),
            $job->jobId(),
            $job->queueName(),
            (string) ($worker['nodeId'] ?? ''),
            (string) ($worker['workerId'] ?? ''),
            $leaseId,
            true,
            'assigned',
            date('c')
        );
    }

    public static function failed(DistributedScheduleJob $job, string $reason): self
    {
        return new self(
            'assignment_' . substr(hash('sha256', $job->jobId() . $reason . microtime(true)), 0, 20),
            $job->jobId(),
            $job->queueName(),
            '',
            '',
            '',
            false,
            $reason,
            date('c')
        );
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['assignmentId'] ?? ''),
            (string) ($data['jobId'] ?? ''),
            (string) ($data['queueName'] ?? ''),
            (string) ($data['nodeId'] ?? ''),
            (string) ($data['workerId'] ?? ''),
            (string) ($data['leaseId'] ?? ''),
            (bool) ($data['assigned'] ?? false),
            (string) ($data['reason'] ?? ''),
            (string) ($data['assignedAt'] ?? '')
        );
    }

    public function assignmentId(): string { return $this->assignmentId; }

    public function isAssigned(): bool
    {
        return $this->assigned;
    }

    public function toArray(): array
    {
        return [
            'assignmentId' => $this->assignmentId,
            'jobId' => $this->jobId,
            'queueName' => $this->queueName,
            'nodeId' => $this->nodeId,
            'workerId' => $this->workerId,
            'leaseId' => $this->leaseId,
            'assigned' => $this->assigned,
            'reason' => $this->reason,
            'assignedAt' => $this->assignedAt !== '' ? $this->assignedAt : date('c'),
        ];
    }
}
