<?php

namespace App\Controller;

use App\Repository\ScanSessionRepository;
use App\Security\Voter\ScanVoter;
use App\Service\ImageStorage;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

/**
 * Serve les images scannées, restreint aux scans visibles dans le périmètre de l'utilisateur (ScanVoter::VIEW).
 * L'image est localisée via l'email du *créateur* du scan, pas du viewer (visibilité partagée par concession).
 */
#[IsGranted('ROLE_USER')]
final class ImageController extends AbstractController
{
    #[Route(
        '/api/images/{sessionId}/{imageId}',
        name: 'app_image',
        methods: ['GET'],
        requirements: ['sessionId' => '[0-9a-f-]{36}', 'imageId' => '[0-9a-f-]{36}'],
    )]
    public function serve(
        string $sessionId,
        string $imageId,
        ScanSessionRepository $sessions,
        ImageStorage $storage,
    ): Response {
        // 404 si la session n'existe pas OU n'est pas dans le périmètre (anti-énumération :
        // on ne distingue pas "inexistant" de "interdit").
        $session = $sessions->findOneById($sessionId);
        if (null === $session || !$this->isGranted(ScanVoter::VIEW, $session)) {
            throw $this->createNotFoundException();
        }

        $path = $storage->pathFor($session->getUserEmail(), $sessionId, $imageId);
        if (null === $path) {
            throw $this->createNotFoundException();
        }

        $response = new BinaryFileResponse($path);
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE, $imageId . '.jpg');
        $response->headers->set('Content-Type', 'image/jpeg');
        $response->headers->set('Cache-Control', 'private, max-age=3600');

        return $response;
    }
}
