<?php

declare(strict_types=1);

namespace Archive\Archived;

use App\Framework\Cache\Cache;

final readonly class FragmentCacheManager
{
    public function __construct(
        private Cache $cache,
    ) {}

    public function hasFragment(string $key, array $dependencies = [], int $ttl = 300): bool
    {
        $cacheKey = $this->buildFragmentKey($key, $dependencies);
        return $this->cache->has($cacheKey);
    }

    public function cacheFragment(string $key, callable $generator, array $dependencies = [], int $ttl = 300): string
    {
        $cacheKey = $this->buildFragmentKey($key, $dependencies);

        return $this->cache->remember(
            $cacheKey,
            $generator,
            $ttl
        )->value;
    }

    public function cacheStaticFragment(string $fragmentId, string $content, array $dependencies = []): void
    {
        $cacheKey = $this->buildFragmentKey($fragmentId, $dependencies);

        // Statische Fragmente haben lange TTL
        $this->cache->set($cacheKey, $content, 3600);
    }

    public function getDynamicFragment(string $fragmentId, callable $generator, array $context = []): string
    {
        // Dynamische Fragmente werden nicht gecacht, aber durch den Generator optimiert
        return $generator($context);
    }

    public function invalidateFragment(string $key, array $dependencies = []): void
    {
        $cacheKey = $this->buildFragmentKey($key, $dependencies);
        $this->cache->forget($cacheKey);
    }

    public function invalidateByPattern(string $pattern): int
    {
        // Vereinfacht - das Cache-Interface bietet möglicherweise keine Pattern-Invalidierung
        // Hier könnten wir eine erweiterte Implementierung hinzufügen
        return 0;
    }

    public function getFragment(string $key, array $dependencies = []): ?string
    {
        $cacheKey = $this->buildFragmentKey($key, $dependencies);

        if ($this->cache->has($cacheKey)) {
            return $this->cache->get($cacheKey)->value;
        }

        return null;
    }

    public function warmupFragment(string $key, callable $generator, array $dependencies = [], int $ttl = 300): void
    {
        $this->cacheFragment($key, $generator, $dependencies, $ttl);
    }

    public function getFragmentStats(): array
    {
        return [
            'cache_enabled' => true,
            'cache_interface' => get_class($this->cache),
        ];
    }

    private function buildFragmentKey(string $key, array $dependencies): string
    {
        $dependencyHash = '';
        if (!empty($dependencies)) {
            ksort($dependencies); // Konsistente Reihenfolge
            $dependencyHash = ':' . md5(serialize($dependencies));
        }

        return "fragment:{$key}{$dependencyHash}";
    }
}
