<?php
declare(strict_types=1);

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

final class DistributedQueuePartition
{
    public function __construct(
        private readonly string $partitionId,
        private readonly string $queueName,
        private readonly string $nodeId = '',
        private readonly string $workerId = '',
        private readonly int $weight = 1,
        private readonly string $assignedAt = ''
    ) {}

    public static function assign(string $queueName, string $nodeId, string $workerId, int $weight = 1): self
    {
        $partitionId = 'partition_' . substr(hash('sha256', $queueName . $nodeId . $workerId . microtime(true)), 0, 20);

        return new self($partitionId, $queueName, $nodeId, $workerId, max(1, $weight), date('c'));
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['partitionId'] ?? ''),
            (string) ($data['queueName'] ?? ''),
            (string) ($data['nodeId'] ?? ''),
            (string) ($data['workerId'] ?? ''),
            (int) ($data['weight'] ?? 1),
            (string) ($data['assignedAt'] ?? '')
        );
    }

    public function partitionId(): string { return $this->partitionId; }
    public function queueName(): string { return $this->queueName; }
    public function nodeId(): string { return $this->nodeId; }
    public function workerId(): string { return $this->workerId; }

    public function toArray(): array
    {
        return [
            'partitionId' => $this->partitionId,
            'queueName' => $this->queueName,
            'nodeId' => $this->nodeId,
            'workerId' => $this->workerId,
            'weight' => max(1, $this->weight),
            'assignedAt' => $this->assignedAt !== '' ? $this->assignedAt : date('c'),
        ];
    }
}
