<?php

declare(strict_types=1);

namespace Archive\Archived;

use App\Framework\View\RenderContext;

final class TemplatePreprocessor
{
    private array $normalizedTemplates = [];

    public function normalizeTemplate(string $template, RenderContext $context): string
    {
        $cacheKey = md5($template . serialize($context->data));

        if (isset($this->normalizedTemplates[$cacheKey])) {
            return $this->normalizedTemplates[$cacheKey];
        }

        $normalized = $template;

        // Entferne Kommentare für konsistentere Cache-Keys
        $normalized = preg_replace('/<!--.*?-->/s', '', $normalized);

        // Normalisiere Whitespace
        $normalized = preg_replace('/\s+/', ' ', $normalized);
        $normalized = trim($normalized);

        // Cache das normalisierte Template
        $this->normalizedTemplates[$cacheKey] = $normalized;

        return $normalized;
    }

    public function extractCacheableBlocks(string $template): array
    {
        $blocks = [];

        // Finde data-cache Attribute für explizite Cache-Bereiche
        if (preg_match_all('/<[^>]+data-cache="([^"]+)"[^>]*>(.*?)<\/[^>]+>/s', $template, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $match) {
                $blocks[] = [
                    'id' => $match[1],
                    'content' => $match[2],
                    'type' => 'explicit'
                ];
            }
        }

        // Finde wiederholende Strukturen (Listen, Cards etc.)
        if (preg_match_all('/<(ul|ol|div class="[^"]*list[^"]*")[^>]*>(.*?)<\/\1>/s', $template, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $i => $match) {
                $blocks[] = [
                    'id' => 'list_block_' . $i,
                    'content' => $match[2],
                    'type' => 'list'
                ];
            }
        }

        return $blocks;
    }

    public function generateOptimizedCacheKey(RenderContext $context, array $dependencies = []): string
    {
        $keyParts = [
            $context->template,
            $context->controllerClass ?? 'default',
        ];

        // Füge nur relevante Daten hinzu (nicht alles aus $context->data)
        $relevantData = $this->extractRelevantData($context->data, $dependencies);
        if (!empty($relevantData)) {
            $keyParts[] = md5(serialize($relevantData));
        }

        // Füge Template-Änderungszeit hinzu für Auto-Invalidation
        $templatePath = $this->resolveTemplatePath($context->template);
        if (file_exists($templatePath)) {
            $keyParts[] = filemtime($templatePath);
        }

        return implode(':', $keyParts);
    }

    private function extractRelevantData(array $data, array $dependencies): array
    {
        if (empty($dependencies)) {
            return $data;
        }

        $relevant = [];
        foreach ($dependencies as $key) {
            if (isset($data[$key])) {
                $relevant[$key] = $data[$key];
            }
        }

        return $relevant;
    }

    private function resolveTemplatePath(string $template): string
    {
        // Vereinfachte Template-Pfad-Auflösung
        return "views/{$template}.php";
    }
}
