<?php

declare(strict_types=1);

namespace App\Framework\HttpClient\Middleware;

use App\Framework\Cache\Cache;
use App\Framework\HttpClient\ClientRequest;
use App\Framework\HttpClient\ClientResponse;
use App\Framework\HttpClient\HttpClientMiddleware;

final readonly class CachingMiddleware implements HttpClientMiddleware
{
    public function __construct(
        private Cache $cache,
        private int $defaultTtl = 300
    ) {
    }

    public function __invoke(ClientRequest $request, callable $next): ClientResponse
    {
        // Nur GET-Requests cachen
        if ($request->method->value !== 'GET') {
            return $next($request);
        }

        $cacheKey = $this->generateCacheKey($request);

        // Prüfe Cache
        $cachedResponse = $this->cache->get($cacheKey);
        if ($cachedResponse instanceof ClientResponse) {
            return $cachedResponse;
        }

        // Response holen und cachen
        $response = $next($request);

        if ($response->isSuccessful()) {
            $ttl = $this->calculateTtl($response);
            $this->cache->set($cacheKey, $response, $ttl);
        }

        return $response;
    }

    private function generateCacheKey(ClientRequest $request): string
    {
        return 'http_client_' . md5($request->url . serialize($request->headers->all()));
    }

    private function calculateTtl(ClientResponse $response): int
    {
        $cacheControl = $response->headers->get('Cache-Control')[0] ?? '';
        ;

        if ($cacheControl && preg_match('/max-age=(\d+)/', $cacheControl, $matches)) {
            return (int) $matches[1];
        }

        return $this->defaultTtl;
    }
}
