<?php

declare(strict_types=1);

namespace App\Framework\View;

use App\Framework\Attributes\Singleton;
use App\Framework\Cache\Cache;
use App\Framework\Core\PathProvider;
use App\Framework\DI\Container;
use App\Framework\DI\DefaultContainer;
use App\Framework\Filesystem\FileStorage;
use App\Framework\Performance\PerformanceService;
use App\Framework\View\Caching\Analysis\SmartTemplateAnalyzer;
use App\Framework\View\Caching\CacheManager;
use App\Framework\View\Caching\TaggedFragmentCache;
use App\Framework\View\Caching\TemplateContext;
use App\Framework\View\Loading\TemplateLoader;

#[Singleton]
final readonly class Engine implements TemplateRenderer
{
    #private ?TemplateRenderer $smartCache;

    private ?CacheManager $cacheManager;

    public function __construct(
        private TemplateLoader    $loader,
        # private PathProvider         $pathProvider,
        private PerformanceService $performanceService,
        private TemplateProcessor $processor,
        #private FileStorage       $storage = new FileStorage('/'),
        #private string            $cachePath = __DIR__ . "/cache",
        #private Container        $container = new DefaultContainer(),
        #private bool             $useSmartCache = true,
        #private bool             $legacyCacheEnabled = false,
        ?Cache                   $cache = null,
        private bool             $cacheEnabled = false,
    ) {
        // Stelle sicher, dass das Cache-Verzeichnis existiert
        #if (! is_dir($this->cachePath)) {
        #    mkdir($this->cachePath, 0755, true);
        #}

        // Neues Cache-System initialisieren
        if ($this->cacheEnabled && $cache) {
            $analyzer = new SmartTemplateAnalyzer($this->loader);
            $fragmentCache = new TaggedFragmentCache($cache);

            $this->cacheManager = new CacheManager(
                cache: $cache,
                analyzer: $analyzer,
                fragmentCache: $fragmentCache
            );
        } else {
            $this->cacheManager = null;
        }
    }

    public function render(RenderContext $context): string
    {
        // Use cache manager if enabled, otherwise render directly
        if ($this->cacheManager !== null) {
            $templateContext = new TemplateContext(
                template: $context->template,
                data: $context->data,
                controllerClass: $context->controllerClass,
                metadata: $context->metaData ? ['meta' => $context->metaData] : []
            );

            return $this->cacheManager->render($templateContext, function () use ($context) {
                return $this->renderDirect($context);
            });
        }

        // Fallback to direct rendering when cache is disabled
        return $this->renderDirect($context);
    }

    private function renderDirect(RenderContext $context): string
    {
        // Load template content
        $content = $this->loader->load($context->template, $context->controllerClass, $context);

        // Process template through DOM pipeline
        return $this->processor->render($context, $content);
    }

    public function invalidateCache(?string $template = null): int
    {
        return $this->cacheManager?->invalidateTemplate($template) ?? 0;
    }

    public function getCacheStats(): array
    {
        if (! $this->cacheManager) {
            return ['cache_enabled' => false];
        }

        return [
            'cache_enabled' => true,
            'cache_manager' => $this->cacheManager->getStats(), // Diese Methode müsstest du noch implementieren
        ];
    }

    public function renderPartial(RenderContext $context): string
    {
        // CRITICAL DEBUG - Check if renderPartial is being called instead of render
        file_put_contents('/tmp/debug.log', "=== ENGINE::RENDERPARTIAL ENTRY POINT === Template: " . $context->template . "\n", FILE_APPEND | LOCK_EX);
        error_log("=== ENGINE::RENDERPARTIAL ENTRY POINT === Template: " . $context->template);

        return $this->renderDirect($context);
    }
}
