<?php

declare(strict_types=1);

namespace App\Module\Directory\Infrastructure\Controller;

use App\Module\Directory\Domain\Repository\ReportDocumentRepositoryInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

final class ReportDocumentDownloadController
{
    private const INLINE_MIME_TYPES = [
        'image/jpeg', 'image/png', 'image/gif', 'image/webp',
        'application/pdf',
    ];

    public function __construct(
        private readonly ReportDocumentRepositoryInterface $repository,
        private readonly string $uploadDir,
    ) {}

    #[Route('/api/report_documents/{id}/download', name: 'report_document_download', methods: ['GET'], priority: 1)]
    #[IsGranted('IS_AUTHENTICATED_FULLY')]
    public function __invoke(int $id): Response
    {
        $document = $this->repository->findById($id);

        if (null === $document || null === $document->getFileName()) {
            throw new NotFoundHttpException('Document not found.');
        }

        $filePath = $this->uploadDir.'/'.$document->getFileName();

        if (!is_file($filePath)) {
            throw new NotFoundHttpException('File missing on disk.');
        }

        $response = new BinaryFileResponse($filePath);
        $mimeType = (string) $document->getMimeType();

        $disposition = in_array($mimeType, self::INLINE_MIME_TYPES, true)
            ? ResponseHeaderBag::DISPOSITION_INLINE
            : ResponseHeaderBag::DISPOSITION_ATTACHMENT;

        $response->setContentDisposition($disposition, (string) $document->getOriginalName());
        $response->headers->set('Content-Type', $mimeType);
        $response->headers->set('X-Content-Type-Options', 'nosniff');

        return $response;
    }
}
