<?php

declare(strict_types=1);

/*
 * This file is part of the VitiCore 2.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Service\Uploader;

use Cocur\Slugify\Slugify;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Filesystem\Filesystem;
use CpCreation\VitiCore\Media\Model\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class FileUploader
{
    public function __construct(
        private Filesystem $filesystem,
    ) {
    }

    public function upload(UploadedFile $file): File
    {
        return $this->uploadFile($file);
    }

    private function uploadFile(UploadedFile $uploadedFile): File
    {
        $slugify = new Slugify();

        $originalName = $uploadedFile->getClientOriginalName();
        $mimeType = $uploadedFile->getClientMimeType() ?? 'application/octet-stream';
        $size = $uploadedFile->getSize() ?? 0;

        $extension = $uploadedFile->guessExtension() ?? $uploadedFile->getClientOriginalExtension() ?? 'bin';
        $baseName = pathinfo($originalName, \PATHINFO_FILENAME);
        $fileName = $slugify->slugify($baseName).'-'.substr(md5(uniqid('', true)), 0, 5).'.'.$extension;

        $path = $uploadedFile->getRealPath();

        if (false === $path) {
            throw new \RuntimeException('Unable to read uploaded file path.');
        }

        $stream = fopen($path, 'rb');

        if (false === $stream) {
            throw new \RuntimeException('Unable to open uploaded file stream.');
        }

        try {
            $this->filesystem->fs('file')->writeStream($fileName, $stream);
        } finally {
            fclose($stream);
        }

        $file = new File();
        $file->setOriginalName($originalName);
        $file->setPath($fileName);
        $file->setMimeType($mimeType);
        $file->setSize($size);

        return $file;
    }
}
