<?php

declare(strict_types=1);

use App\Framework\Queue\ValueObjects\WorkerId;

describe('WorkerId Value Object', function () {
    it('can generate unique worker IDs', function () {
        $workerId1 = WorkerId::generate();
        $workerId2 = WorkerId::generate();

        expect($workerId1->toString())->not->toBe($workerId2->toString());
        expect($workerId1->equals($workerId2))->toBeFalse();
    });

    it('can create deterministic IDs for host and process combinations', function () {
        $workerId1 = WorkerId::forHost('app-server-1', 1001);
        $workerId2 = WorkerId::forHost('app-server-1', 1001);
        $workerId3 = WorkerId::forHost('app-server-2', 1001);

        // Same host/PID should create different IDs (due to ULID component)
        expect($workerId1->toString())->not->toBe($workerId2->toString());

        // Different hosts should create different IDs
        expect($workerId1->toString())->not->toBe($workerId3->toString());
    });

    it('can create worker ID from existing string', function () {
        $originalId = 'test-worker-id-123';
        $workerId = WorkerId::fromString($originalId);

        expect($workerId->toString())->toBe($originalId);
        expect($workerId->getValue())->toBe($originalId);
    });

    it('validates worker ID is not empty', function () {
        expect(fn () => WorkerId::fromString(''))
            ->toThrow(\InvalidArgumentException::class, 'WorkerId cannot be empty');
    });

    it('supports equality comparison', function () {
        $id = 'same-worker-id';
        $workerId1 = WorkerId::fromString($id);
        $workerId2 = WorkerId::fromString($id);
        $workerId3 = WorkerId::fromString('different-id');

        expect($workerId1->equals($workerId2))->toBeTrue();
        expect($workerId1->equals($workerId3))->toBeFalse();
    });

    it('provides string conversion methods', function () {
        $id = 'test-worker-id';
        $workerId = WorkerId::fromString($id);

        expect($workerId->toString())->toBe($id);
        expect($workerId->getValue())->toBe($id);
        expect((string) $workerId)->toBe($id);
    });

    it('supports JSON serialization', function () {
        $id = 'json-serializable-worker-id';
        $workerId = WorkerId::fromString($id);

        expect($workerId->jsonSerialize())->toBe($id);
        expect(json_encode($workerId))->toBe('"' . $id . '"');
    });
});
