<?php

declare(strict_types=1);

namespace App\State\Processor\Core;

use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\ApiResources\Core\File\Upload;
use App\Entity\Access\Access;
use App\Service\File\Exception\FileNotFoundException;
use App\Service\File\FileManager;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Response;

/**
 * Custom provider pour le téléchargement des fichiers du LocalStorage.
 */
final class UploadRequestProcessor implements ProcessorInterface
{
    public function __construct(
        private Security $security,
        private readonly FileManager $fileManager,
    ) {
    }

    /**
     * @param array<mixed> $uriVariables
     * @param array<mixed> $context
     *
     * @throws FileNotFoundException
     */
    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): Upload
    {
        if ($operation instanceof Delete) {
            throw new \RuntimeException('not supported', Response::HTTP_METHOD_NOT_ALLOWED);
        }

        /** @var Access $author */
        $author = $this->security->getUser();

        /** @var Upload $uploadRequest */
        $uploadRequest = $data;

        if (empty($uploadRequest->getFilename())) {
            throw new \RuntimeException('Missing filename', Response::HTTP_BAD_REQUEST);
        }
        if (empty($uploadRequest->getContent())) {
            throw new \RuntimeException('Provided content is empty', Response::HTTP_BAD_REQUEST);
        }

        $file = $this->fileManager->makeFile(
            $uploadRequest->isOrganizationOwned() ? $author->getOrganization() : $author,
            $uploadRequest->getFilename(),
            $uploadRequest->getType(),
            base64_decode($uploadRequest->getContent()),
            $author,
            false,
            $uploadRequest->getVisibility(),
            $uploadRequest->getMimeType(),
            $uploadRequest->getConfig()
        );

        $uploadRequest->setFileId($file->getId());

        return $uploadRequest;
    }
}
