<?php

namespace App\Modules\Media\Infrastructure;

use App\Modules\Media\Domain\VideoThumbnailCreator;
use FFMpeg\Coordinate\TimeCode;
use FFMpeg\FFMpeg;
use FFMpeg\FFProbe;
use Intervention\Image\ImageManagerStatic;


class MemoryVideoThumbnailCreator implements VideoThumbnailCreator
{
    public function create(string $src, int $width, int $height, string $ext): string
    {
        $config = [
            'ffmpeg.binaries'  => config('var.FFMPEG'),
            'ffprobe.binaries' => config('var.FFPROBE')
        ];

        $ffprobe = FFProbe::create($config);
        $ffmpeg = FFMpeg::create($config);

        $duration = $this->getDuration($ffprobe, $src);

        $video = $ffmpeg->open($src);

        $path = config('var.PATH_PRIVATE') . 'temp' . DIRECTORY_SEPARATOR . uniqid() . '.' . $ext;

        try {
            $video->frame(TimeCode::fromSeconds($duration))
                ->save($path);

            $value = $this->fitImage($path, $ext, $width, $height);
        } catch (\Exception $e) {
            return '';
        }
        unlink($path);
        return $value;
    }

    public function createScale(string $src, int $width, int $height, string $ext): string
    {
        $config = [
            'ffmpeg.binaries'  => config('var.FFMPEG'),
            'ffprobe.binaries' => config('var.FFPROBE')
        ];

        $ffprobe = FFProbe::create($config);
        $ffmpeg = FFMpeg::create($config);

        $duration = $this->getDuration($ffprobe, $src);
        $video = $ffmpeg->open($src);

        $path = config('var.PATH_PRIVATE') . 'temp' . DIRECTORY_SEPARATOR . uniqid() . '.' . $ext;

        try {
            $video->frame(TimeCode::fromSeconds($duration))
                ->save($path);
            $value = $this->scaleImage($path, $ext, $width, $height);
        } catch (\Exception $e) {
            return '';
        }

        unlink($path);
        return $value;
    }

    private function fitImage(string $path, string $ext, int $width, int $height)
    {
        $imageThumb = ImageManagerStatic::make($path);
        $imageThumb->fit($width, $height, function ($constraint) {
            $constraint->upsize();
        });
        return $imageThumb->encode($ext);
    }

    private function scaleImage(string $path, string $ext, int $width, int $height)
    {
        $imageThumb = ImageManagerStatic::make($path);
        $imageThumb->scale($width, $height);
        return $imageThumb->encode($ext);
    }

    private function getDuration(FFProbe $ffprobe, string $src): float
    {
        $duration = (float)$ffprobe->format($src)->get('duration');
        $secs = 1;
        if ($duration > $secs) {
            $secs = $duration / 2;
        }
        return $secs;
    }
}
