<?php

declare(strict_types=1);

namespace App\Framework\View;

use App\Framework\Cache\Cache;
use App\Framework\Core\PathProvider;
use App\Framework\DI\DefaultContainer;
use App\Framework\DI\Initializer;
use App\Framework\Discovery\Results\DiscoveryRegistry;
use App\Framework\Performance\PerformanceService;
use App\Framework\View\Dom\Transformer\AssetInjectorTransformer;
use App\Framework\View\Dom\Transformer\CommentStripTransformer;
use App\Framework\View\Dom\Transformer\ForTransformer;
use App\Framework\View\Dom\Transformer\HoneypotTransformer;
use App\Framework\View\Dom\Transformer\IfTransformer;
use App\Framework\View\Dom\Transformer\LayoutTagTransformer;
use App\Framework\View\Dom\Transformer\MetaManipulatorTransformer;
use App\Framework\View\Dom\Transformer\WhitespaceCleanupTransformer;
use App\Framework\View\Dom\Transformer\XComponentTransformer;
use App\Framework\View\Loading\TemplateLoader;
use App\Framework\View\Processors\PlaceholderReplacer;
use App\Framework\View\Processors\VoidElementsSelfClosingProcessor;

final readonly class TemplateRendererInitializer
{
    public function __construct(
        private DefaultContainer $container,
        private DiscoveryRegistry $results,
    ) {}

    #[Initializer]
    public function __invoke(): TemplateRenderer
    {
        // AST Transformers (new approach) - Modern template processing
        $astTransformers = [
            // Core transformers (order matters!)
            LayoutTagTransformer::class,            // Process <layout> tags FIRST (before other processing)
            XComponentTransformer::class,           // Process <x-*> components (LiveComponents + HtmlComponents)
            ForTransformer::class,                  // Process foreach loops and <for> elements (BEFORE if/placeholders)
            IfTransformer::class,                   // Conditional rendering (if/condition attributes)
            MetaManipulatorTransformer::class,      // Set meta tags from context
            AssetInjectorTransformer::class,        // Inject Vite assets (CSS/JS)
            HoneypotTransformer::class,             // Add honeypot spam protection to forms
            CommentStripTransformer::class,         // Remove HTML comments
            WhitespaceCleanupTransformer::class,    // Remove empty text nodes
        ];

        // TODO: Migrate remaining DOM processors to AST transformers:
        // - ComponentProcessor (for <component> tags) - COMPLEX, keep in DOM for now
        // - TableProcessor (for table rendering) - OPTIONAL
        // - FormProcessor (for form handling) - OPTIONAL

        $strings = [
            PlaceholderReplacer::class,       // PlaceholderReplacer handles simple {{ }} replacements
            VoidElementsSelfClosingProcessor::class,
        ];

        /** @var Cache $cache */
        $cache = $this->container->get(Cache::class);

        // Performance-Optimierungen (optional)
        $chainOptimizer = new ProcessorChainOptimizer($cache);
        $compiledTemplateCache = new CompiledTemplateCache($cache);

        // Performance Tracker nur in Development/Profiling
        $performanceTracker = null;
        if (getenv('ENABLE_TEMPLATE_PROFILING') === 'true') {
            $performanceTracker = new ProcessorPerformanceTracker();
            $performanceTracker->enable();
        }

        $templateProcessor = new TemplateProcessor(
            astTransformers: $astTransformers,
            stringProcessors: $strings,
            container: $this->container,
            chainOptimizer: $chainOptimizer,
            compiledTemplateCache: $compiledTemplateCache,
            performanceTracker: $performanceTracker
        );

        $this->container->singleton(TemplateProcessor::class, $templateProcessor);

        /** @var PathProvider $pathProvider */
        $pathProvider = $this->container->get(PathProvider::class);
        /** @var Cache $cache */
        $cache = $this->container->get(Cache::class);

        /** @var PerformanceService $performanceService */
        $performanceService = $this->container->get(PerformanceService::class);

        // Define caching state centrally
        $cacheEnabled = false;  // Keep caching disabled while debugging template processing

        $loader = new TemplateLoader(
            pathProvider: $pathProvider,
            cache: $cache,
            discoveryRegistry: $this->results,
            cacheEnabled: $cacheEnabled  // Pass cache state to loader
        );

        $this->container->singleton(TemplateLoader::class, $loader);

        return new Engine(
            loader: $loader,
            performanceService: $performanceService,
            processor: $templateProcessor,
            cache: $cache,
            cacheEnabled: $cacheEnabled,  // Use same cache state for Engine
        );
    }
}
