<?php

namespace App\Application\Media;

use App\Domain\Media\ImageRepository;
use App\Domain\Media\ImageVariantRepository;
use App\Framework\Attributes\Route;
use App\Framework\Core\PathProvider;
use App\Framework\Router\Result\FileResult;

final readonly class ShowImage
{
    public function __construct(
        private PathProvider $pathProvider,
        private ImageRepository $imageRepository,
        private ImageVariantRepository $imageVariantRepository,
    ) {}
    #[Route('/images/{filename}')]
    public function __invoke($filename): FileResult
    {
        $path = $this->pathProvider->resolvePath('storage/uploads/');

        $image = $this->imageRepository->findByFilename($filename);

        if($image === null) {
            $image = $this->imageVariantRepository->findByFilename($filename);
        }

        if($image === null) {
            throw new \Exception('Image not found');
        }

        $file = $image->path . $image->filename;

        if (file_exists($file)) {
            header('Content-Type: image/jpeg');
            header('Content-Length: '.filesize($file));
            // optional: Caching-Header
            header('Cache-Control: public, max-age=86400');

            // Hier: Download-Dateiname vorschlagen
            // inline = im Browser anzeigen; attachment = Download erzwingen
            header('Content-Disposition: inline; filename="' . $image->filename . '-2025"');
            // oder
            // header('Content-Disposition: attachment; filename="' . basename($filename) . '"');

            // 1. Last-Modified & ETag (Conditional Requests)
            $lastModified = gmdate('D, d M Y H:i:s', filemtime($file)).' GMT';
            $eTag         = '"'.md5_file($file).'"';
            header("Last-Modified: $lastModified");
            header("ETag: $eTag");

            // 304 Not Modified – wenn Browser-Cache gültig
            if (
                (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) === $eTag) ||
                (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] === $lastModified)
            ) {
                http_response_code(304);
                exit;
            }

            // 2. Expires (optional, zusätzlich zu Cache-Control)
            $expireTime = gmdate('D, d M Y H:i:s', time() + 86400).' GMT';
            header("Expires: $expireTime");

            // 3. Accept-Ranges (für Partial-Requests / Resuming)
            header('Accept-Ranges: bytes');

            // 4. Vary (bei Content-Negotiation, z. B. für WebP)
            header('Vary: Accept');

            // 5. Security-Header
            // Verhindert MIME-Sniffing
            header('X-Content-Type-Options: nosniff');
            // Schutz gegen Clickjacking (falls du Bilder in iframes erlauben willst, ggf. anpassen)
            header('X-Frame-Options: SAMEORIGIN');
            // Referrer-Policy für Bildanfragen
            header('Referrer-Policy: no-referrer-when-downgrade');

            // 6. Content-Security-Policy (CSP) – strengere Kontrolle, wenn du das Bild per <img> einbindest
            // Hier als Beispiel nur für Bilder aus eigenem Domain
            header("Content-Security-Policy: default-src 'self'; img-src 'self';");

            readfile($file);

            exit;
        }



        return new FileResult($file);
    }
}
