<?php

declare(strict_types=1);

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\Core\AppBootstrapper;
use App\Framework\DateTime\SystemClock;
use App\Framework\DateTime\SystemHighResolutionClock;
use App\Framework\Performance\EnhancedPerformanceCollector;
use App\Framework\Performance\MemoryMonitor;
use App\Framework\Queue\Queue;
use App\Framework\Queue\ValueObjects\JobPayload;

// Named job class
final class TestJob
{
    public function __construct(
        private readonly string $message = 'Default test message'
    ) {
    }

    public function handle(): string
    {
        $result = "TestJob executed: {$this->message} at " . date('Y-m-d H:i:s');
        echo "🎯 $result\n";
        file_put_contents('/tmp/queue-job-executed.txt', $result . "\n", FILE_APPEND);

        return $result;
    }

    public function getType(): string
    {
        return 'test-job';
    }

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

echo "🔧 Testing Queue with Named Job Class\n";
echo "====================================\n\n";

try {
    // Bootstrap framework
    $clock = new SystemClock();
    $highResClock = new SystemHighResolutionClock();
    $memoryMonitor = new MemoryMonitor();
    $collector = new EnhancedPerformanceCollector($clock, $highResClock, $memoryMonitor, enabled: false);

    $bootstrapper = new AppBootstrapper(__DIR__ . '/../..', $collector, $memoryMonitor);
    $container = $bootstrapper->bootstrapWorker();

    $queue = $container->get(Queue::class);

    echo "✅ Framework bootstrapped successfully\n";
    echo "✅ Queue service retrieved\n\n";

    // Clean previous test file
    if (file_exists('/tmp/queue-job-executed.txt')) {
        unlink('/tmp/queue-job-executed.txt');
    }

    // Test 1: Push named job class
    echo "📋 Test 1: Push Named Job Class\n";
    echo "------------------------------\n";

    $testJob = new TestJob('Hello from Queue!');

    try {
        $jobPayload = JobPayload::immediate($testJob);
        echo "✅ JobPayload created successfully\n";

        $queue->push($jobPayload);
        echo "✅ Job pushed to queue successfully\n";

        $size = $queue->size();
        echo "📊 Queue size after push: $size\n";

    } catch (Exception $e) {
        echo "❌ Failed to push job: " . $e->getMessage() . "\n";
        echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
    }
    echo "\n";

    // Test 2: Pop and execute job
    echo "📋 Test 2: Pop and Execute Job\n";
    echo "-----------------------------\n";

    try {
        $jobPayload = $queue->pop();

        if ($jobPayload) {
            echo "✅ Job popped from queue\n";
            echo "📊 Job type: " . $jobPayload->job->getType() . "\n";
            echo "📊 Job message: " . $jobPayload->job->getMessage() . "\n";

            if (method_exists($jobPayload->job, 'handle')) {
                echo "✅ Executing job...\n";
                $result = $jobPayload->job->handle();
                echo "✅ Job executed successfully\n";
            } else {
                echo "❌ Job doesn't have handle method\n";
            }

        } else {
            echo "❌ No jobs in queue\n";
        }

        $finalSize = $queue->size();
        echo "📊 Queue size after pop: $finalSize\n";

    } catch (Exception $e) {
        echo "❌ Failed to pop/execute job: " . $e->getMessage() . "\n";
        echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
    }
    echo "\n";

    // Test 3: Check execution log
    echo "📋 Test 3: Verify Job Execution\n";
    echo "------------------------------\n";

    if (file_exists('/tmp/queue-job-executed.txt')) {
        echo "✅ Job execution verified (log file created)\n";
        $content = file_get_contents('/tmp/queue-job-executed.txt');
        echo "📄 Job execution log:\n";
        echo $content;
    } else {
        echo "❌ No job execution log found\n";
    }
    echo "\n";

    // Test 4: Push multiple jobs
    echo "📋 Test 4: Push Multiple Jobs\n";
    echo "----------------------------\n";

    for ($i = 1; $i <= 3; $i++) {
        $job = new TestJob("Message #$i");
        $jobPayload = JobPayload::immediate($job);
        $queue->push($jobPayload);
        echo "✅ Pushed job #$i\n";
    }

    $multiSize = $queue->size();
    echo "📊 Queue size with multiple jobs: $multiSize\n";

    // Process all jobs
    echo "\n🔄 Processing all jobs:\n";
    while ($queue->size() > 0) {
        $jobPayload = $queue->pop();
        if ($jobPayload) {
            $jobPayload->job->handle();
        }
    }

    $emptySize = $queue->size();
    echo "📊 Queue size after processing all: $emptySize\n";

} catch (Exception $e) {
    echo "❌ Queue test with named class failed: " . $e->getMessage() . "\n";
    echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
    exit(1);
}

echo "\n🎯 Queue with named job class test completed!\n";
