<?php

declare(strict_types=1);

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

use App\Framework\CommandBus\Attributes\CommandHandler;
use App\Framework\CommandBus\CommandBus;
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\RetryStrategyHelper;
use App\Framework\Queue\ValueObjects\JobPayload;
use App\Framework\Queue\ValueObjects\QueuePriority;

// Test Job Command
final readonly class TestEmailJob
{
    public function __construct(
        public string $recipient,
        public string $subject,
        public string $body
    ) {
    }
}

// Test Job Handler
#[CommandHandler(TestEmailJob::class)]
final readonly class TestEmailJobHandler
{
    public function handle(TestEmailJob $job): array
    {
        echo "📧 Sending email...\n";
        echo "   To: {$job->recipient}\n";
        echo "   Subject: {$job->subject}\n";
        echo "   Body: {$job->body}\n";

        // Simulate email sending work
        sleep(1);

        echo "✅ Email sent successfully!\n\n";

        return [
            'status' => 'sent',
            'recipient' => $job->recipient,
            'sent_at' => date('Y-m-d H:i:s'),
        ];
    }
}

echo "🚀 Testing Queue System with Real Jobs\n";
echo "=====================================\n\n";

try {
    // Create dependencies for enhanced performance collector
    $clock = new SystemClock();
    $highResClock = new SystemHighResolutionClock();
    $memoryMonitor = new MemoryMonitor();
    $collector = new EnhancedPerformanceCollector($clock, $highResClock, $memoryMonitor, enabled: false);

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

    // Get services
    $queue = $container->get(Queue::class);
    $commandBus = $container->get(CommandBus::class);

    echo "✅ Framework bootstrapped successfully\n";
    echo "✅ Queue and CommandBus retrieved\n";
    echo "✅ Command handlers auto-discovered via attributes\n\n";

    // Test 1: Queue a simple job
    echo "📋 Test 1: Queueing a simple job\n";
    echo "---------------------------------\n";

    $testJob = new TestEmailJob(
        recipient: 'user@example.com',
        subject: 'Test Email from Queue System',
        body: 'This is a test email sent through the queue system!'
    );

    $jobPayload = JobPayload::create($testJob);
    $jobId = $queue->push($jobPayload);
    echo "✅ Job queued with ID: {$jobId}\n\n";

    // Test 2: Queue a high priority job
    echo "📋 Test 2: Queueing a high priority job\n";
    echo "---------------------------------------\n";

    $urgentJob = new TestEmailJob(
        recipient: 'admin@example.com',
        subject: 'URGENT: High Priority Test',
        body: 'This is an urgent test email!'
    );

    $urgentJobPayload = JobPayload::create(
        $urgentJob,
        QueuePriority::high(),
        null, // delay
        null, // timeout
        RetryStrategyHelper::forEmails()
    );
    $urgentJobId = $queue->push($urgentJobPayload);
    echo "✅ High priority job queued with ID: {$urgentJobId}\n\n";

    // Test 3: Process jobs
    echo "📋 Test 3: Processing queued jobs\n";
    echo "---------------------------------\n";

    $processedCount = 0;
    $maxJobs = 5; // Process max 5 jobs to avoid infinite loop

    while ($processedCount < $maxJobs) {
        $jobPayload = $queue->pop();

        if (! $jobPayload) {
            echo "ℹ️  No more jobs in queue\n";

            break;
        }

        echo "🔄 Processing job from queue\n";

        try {
            // Get the actual job object from the payload
            $actualJob = $jobPayload->job;

            $result = $commandBus->dispatch($actualJob);
            echo "✅ Job completed successfully\n";
            echo "   Result: " . json_encode($result) . "\n\n";
            $processedCount++;
        } catch (\Exception $e) {
            echo "❌ Job failed: {$e->getMessage()}\n\n";
            $processedCount++;
        }
    }

    echo "📊 Test Results:\n";
    echo "===============\n";
    echo "✅ Queue system is working correctly\n";
    echo "✅ Jobs can be queued and processed\n";
    echo "✅ Priority system is functioning\n";
    echo "✅ Retry strategies can be applied\n";
    echo "✅ Command bus integration works\n";
    echo "📈 Processed {$processedCount} jobs successfully\n";

} catch (\Exception $e) {
    echo "❌ Test failed: {$e->getMessage()}\n";
    echo "Stack trace:\n{$e->getTraceAsString()}\n";
    exit(1);
}

echo "\n🎉 Queue system test completed successfully!\n";
