<?php

namespace Tricks\MediaLibraryOverrides\Actions;

use Exception;
use Spatie\MediaLibrary\Conversions\Actions\PerformManipulationsAction;
use Spatie\MediaLibrary\Conversions\Conversion;
use Spatie\MediaLibrary\Conversions\Events\ConversionHasBeenCompleted;
use Spatie\MediaLibrary\Conversions\Events\ConversionWillStart;
use Spatie\MediaLibrary\Conversions\ImageGenerators\ImageGeneratorFactory;
use Spatie\MediaLibrary\MediaCollections\Filesystem;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\MediaLibrary\ResponsiveImages\ResponsiveImageGenerator;
use Throwable;
use Tricks\MediaLibraryOverrides\ResponsiveImages\WidthOnlyResponsiveImageGenerator;

class PerformConversionAction extends \Spatie\MediaLibrary\Conversions\Actions\PerformConversionAction
{
    /**
     * @throws Throwable
     */
    public function execute(
        Conversion $conversion,
        Media $media,
        string $copiedOriginalFile
    ): void {
        event(new ConversionWillStart($media, $conversion, $copiedOriginalFile));

        $imageGenerator = ImageGeneratorFactory::forMedia($media);

        throw_unless($imageGenerator, new Exception('No ImageGenerator found for media.'));

        $copiedOriginalFile = $imageGenerator->convert($copiedOriginalFile, $conversion);

        throw_unless($copiedOriginalFile, new Exception('Could not convert copiedOriginalFile.'));

        $manipulationResult = (new PerformManipulationsAction())->execute($media, $conversion, $copiedOriginalFile);

        $newFileName = $conversion->getConversionFile($media);

        $renamedFile = $this->renameInLocalDirectory($manipulationResult, $newFileName);

        if ($conversion->shouldGenerateResponsiveImages()) {
            /** @var ResponsiveImageGenerator $responsiveImageGenerator */
            $responsiveImageGenerator = app(WidthOnlyResponsiveImageGenerator::class);

            $responsiveImageGenerator->generateResponsiveImagesForConversion(
                $media,
                $conversion,
                $renamedFile
            );
        }

        app(Filesystem::class)->copyToMediaLibrary($renamedFile, $media, 'conversions');

        $media->markAsConversionGenerated($conversion->getName());

        event(new ConversionHasBeenCompleted($media, $conversion));
    }
}
