<?php

declare(strict_types=1);

use App\Framework\Queue\Contracts\JobProgressTrackerInterface;
use App\Framework\Queue\Services\ProgressManager;
use App\Framework\Queue\ValueObjects\JobProgress;

beforeEach(function () {
    // Mock the progress tracker interface instead of final classes
    $this->progressTracker = mock(JobProgressTrackerInterface::class);
    $this->progressManager = new ProgressManager($this->progressTracker);
});

it('can start a job', function () {
    $jobId = 'test-job-123';

    $this->progressTracker
        ->shouldReceive('updateProgress')
        ->once()
        ->with($jobId, \Mockery::type(JobProgress::class), null)
        ->andReturn(null);

    $this->progressManager->startJob($jobId);

    expect(true)->toBeTrue(); // If no exception thrown, test passes
});

it('can update job progress', function () {
    $jobId = 'test-job-123';
    $percentage = 50.0;
    $message = 'Halfway done';

    $this->progressTracker
        ->shouldReceive('updateProgress')
        ->once()
        ->with($jobId, \Mockery::type(JobProgress::class), null)
        ->andReturn(null);

    $this->progressManager->updateJobProgress($jobId, $percentage, $message);

    expect(true)->toBeTrue(); // If no exception thrown, test passes
});

it('can complete a job', function () {
    $jobId = 'test-job-123';
    $message = 'Job completed successfully';

    $this->progressTracker
        ->shouldReceive('markJobCompleted')
        ->once()
        ->with($jobId, $message)
        ->andReturn(null);

    $this->progressManager->completeJob($jobId, $message);

    expect(true)->toBeTrue(); // If no exception thrown, test passes
});

it('can create step tracker', function () {
    $jobId = 'test-job-123';
    $steps = [
        ['name' => 'step1', 'description' => 'First step'],
        ['name' => 'step2', 'description' => 'Second step'],
    ];

    $stepTracker = $this->progressManager->createStepTracker($jobId, $steps);

    expect($stepTracker)->toBeInstanceOf(\App\Framework\Queue\Services\StepProgressTracker::class);
    expect($stepTracker->getCurrentStep())->toBe($steps[0]);
    expect($stepTracker->isComplete())->toBeFalse();
    expect($stepTracker->getProgress())->toBe(0.0);
});

it('throws exception for empty steps array', function () {
    $jobId = 'test-job-123';
    $steps = [];

    expect(fn () => $this->progressManager->createStepTracker($jobId, $steps))
        ->toThrow(\InvalidArgumentException::class, 'Steps array cannot be empty');
});

it('throws exception for invalid step structure', function () {
    $jobId = 'test-job-123';
    $steps = [
        ['name' => 'step1'], // Missing description
    ];

    expect(fn () => $this->progressManager->createStepTracker($jobId, $steps))
        ->toThrow(\InvalidArgumentException::class);
});
