<?php

declare(strict_types=1);

namespace App\Service\File\Factory;

use App\Entity\Core\File;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Liip\ImagineBundle\Imagine\Data\DataManager;
use Liip\ImagineBundle\Imagine\Filter\FilterManager;

/**
 * Utilise Liip Imagine Bundle afin de créer les images selon une configuration et les stock dans un cache
 */
class ImageFactory
{
    public function __construct(
        private readonly DataManager $dataManager,
        private readonly FilterManager $filterManager,
        private readonly CacheManager $cacheManager
){}
    /**
     * Permet de créer les images retaillées
     * @param File $file : File contenant l'image de base
     * @param string $filterName : nom du filtre liip à appliquer
     * @return void
     */
    public function createImageContent(File $file, string $filterName): void{
        $filters_options = $this->getCropFilterOptions($file->getConfig());
        $path = $file->getPath();
        $this->createAndStore($path, $filterName, $filters_options);
    }

    /**
     * Créer l'image retaillée et l'à stock l'image dans le cache
     * @param string $path : chemin de l'image
     * @param string $filter : nom du filtre liip à appliquer
     * @param array<string, array<string, array<string, array<int, int>>>> $filtersOptions : options du filtre
     * @return void
     */
    private function createAndStore(string $path, string $filter, array $filtersOptions){
        $binary = $this->dataManager->find($filter, $path);
        $binary = $this->filterManager->applyFilter($binary, $filter, ['filters' => $filtersOptions]);
        $this->cacheManager->store($binary, $path, $filter);
    }

    /**
     * Définit et retourne le tableau de config servant à cropper
     * @param string|null $config : Configuration du File
     * @return array<string, array<string, array<string, array<int, int>>>> | array : tableau de configuration
     * @see ImageUtilsTest::testGetCroppingConfig()
     */
    protected function getCropFilterOptions(?string $config): array{
        if(!$config)
            return [];

        $crop_filters_options = [];
        $config = json_decode($config, true);
        //On s'assure que la hauteur ET la largeur soient > 0
        if($config['width'] > 0 && $config['height'] > 0){
            $crop_filters_options = array_merge(
                [
                    'crop' => array(
                        'size' => [intval($config['width']), intval($config['height'])],
                        'start' => [intval($config['x']), intval($config['y'])]
                    )
                ],
                $crop_filters_options
            );
        }

        return $crop_filters_options;
    }
}