<?php

declare(strict_types=1);

namespace App\Framework\Queue;

use App\Framework\Core\PathProvider;
use App\Framework\DI\Container;
use App\Framework\DI\Initializer;
use App\Framework\Logging\Logger;
use App\Framework\Logging\ValueObjects\LogContext;
use App\Framework\Queue\Exceptions\RedisExtensionNotLoadedException;
use App\Framework\Redis\RedisConfig;
use App\Framework\Redis\RedisConnection;
use App\Framework\Redis\RedisConnectionPool;

final readonly class QueueInitializer
{
    public function __construct(
        private PathProvider $pathProvider,
        private Container $container
    ) {
    }

    #[Initializer]
    public function __invoke(Logger $logger): Queue
    {
        try {
            // Check if Redis extension is available
            if (! extension_loaded('redis')) {
                throw RedisExtensionNotLoadedException::notLoaded();
            }

            // Try to use Redis connection pool if available, otherwise create direct connection

            $pool = $this->container->get(RedisConnectionPool::class);
            $redisConnection = $pool->getQueueConnection();

            return new RedisQueue(
                connection: $redisConnection,
                queueName: 'commands'
            );
        } catch (\Throwable $e) {
            // Fallback to file queue if Redis is not available
            $logger->info("Using file queue (Redis not available)", LogContext::withData([
                'reason' => $e->getMessage(),
                'fallback' => 'FileQueue',
            ]));
            $path = $this->pathProvider->resolvePath('/storage/queue/');

            return new FileQueue($path, logger: $logger);
        }
    }
}
