<?php

declare(strict_types=1);

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

use App\Framework\Cache\Driver\InMemoryCache;
use App\Framework\Cache\GeneralCache;
use App\Framework\Context\ExecutionContext;
use App\Framework\Core\PathProvider;
use App\Framework\DateTime\SystemClock;
use App\Framework\DI\DefaultContainer;
use App\Framework\DI\InitializerMapper;
use App\Framework\Discovery\UnifiedDiscoveryService;
use App\Framework\Discovery\ValueObjects\DiscoveryConfiguration;
use App\Framework\Filesystem\FileSystemService;
use App\Framework\Reflection\CachedReflectionProvider;
use App\Framework\Serializer\Json\JsonSerializer;

echo "=== Testing ALL Initializer Discovery ===\n\n";

try {
    // Setup with correct path
    $projectRoot = dirname(__DIR__, 2);
    $srcPath = $projectRoot . '/src';

    echo "Project root: $projectRoot\n";
    echo "Source path: $srcPath\n";
    echo "Current execution context: " . ExecutionContext::detect()->getType()->value . "\n\n";

    $container = new DefaultContainer();
    $pathProvider = new PathProvider($projectRoot);
    $clock = new SystemClock();
    $fileSystemService = new FileSystemService();
    $reflectionProvider = new CachedReflectionProvider();

    // Create cache for discovery
    $cacheDriver = new InMemoryCache();
    $serializer = new JsonSerializer();
    $cache = new GeneralCache($cacheDriver, $serializer);

    // Create InitializerMapper
    $initializerMapper = new InitializerMapper();

    // Configure discovery for the entire src directory WITHOUT cache
    $config = new DiscoveryConfiguration(
        paths: [$srcPath],
        attributeMappers: [$initializerMapper],
        targetInterfaces: [],
        useCache: false
    );

    // Create discovery service
    $discoveryService = new UnifiedDiscoveryService(
        pathProvider: $pathProvider,
        cache: $cache,
        clock: $clock,
        reflectionProvider: $reflectionProvider,
        configuration: $config,
        attributeMappers: [$initializerMapper],
        targetInterfaces: []
    );

    echo "Starting full discovery scan...\n";

    $registry = $discoveryService->discover();

    echo "Discovery completed!\n\n";

    // Check for Initializers in attribute registry
    $initializerAttributeClass = 'App\\Framework\\DI\\Initializer';
    $initializers = $registry->attributes->get($initializerAttributeClass);

    echo "=== All Found Initializers ===\n";
    echo "Total initializers found: " . count($initializers) . "\n\n";

    if (empty($initializers)) {
        echo "❌ No initializers found!\n";
    } else {
        echo "✅ All found initializers:\n";

        // Group by class for better overview
        $initializersByClass = [];
        foreach ($initializers as $mapping) {
            $className = $mapping->class->getFullyQualified();
            $methodName = $mapping->method ? $mapping->method->toString() : '(class-level)';

            if (! isset($initializersByClass[$className])) {
                $initializersByClass[$className] = [];
            }

            $initializersByClass[$className][] = [
                'method' => $methodName,
                'target' => $mapping->target,
                'return_type' => $mapping->mappedData['return'] ?? 'null',
                'contexts' => $mapping->mappedData['contexts'] ?? null,
                'file' => str_replace($projectRoot, '', $mapping->file->toString()),
            ];
        }

        // Sort by class name for consistent output
        ksort($initializersByClass);

        foreach ($initializersByClass as $className => $methods) {
            $shortName = substr(strrchr($className, '\\'), 1);
            echo "\n📦 $shortName\n";
            echo "   Class: $className\n";

            foreach ($methods as $method) {
                echo "   🔧 Method: {$method['method']}\n";
                echo "      Return: {$method['return_type']}\n";
                echo "      Target: {$method['target']}\n";

                if ($method['contexts']) {
                    echo "      Contexts: " . json_encode($method['contexts']) . "\n";
                }

                echo "      File: {$method['file']}\n";
            }
        }

        echo "\n=== Summary ===\n";
        echo "Classes with initializers: " . count($initializersByClass) . "\n";
        echo "Total initializer methods: " . count($initializers) . "\n";

        // Check for specific missing initializers
        $expectedInitializers = [
            'RequestFactory',
            'CacheInitializer',
            'LoggerInitializer',
            'DatabaseInitializer',
            'SessionInitializer',
        ];

        echo "\n=== Expected Initializers Check ===\n";
        foreach ($expectedInitializers as $expected) {
            $found = false;
            foreach ($initializersByClass as $className => $methods) {
                if (str_contains($className, $expected)) {
                    $found = true;

                    break;
                }
            }
            echo "- $expected: " . ($found ? "✅ Found" : "❌ Missing") . "\n";
        }
    }

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