<?php

namespace Mnv\Core\Uploads;


use Mnv\Core\Config;

use Imagine\Image\Box;
use Imagine\Image\ImageInterface;
use Imagine\Image\ImagineInterface;

use Mnv\Core\Uploads\Exceptions\InvalidParamException;

use Symfony\Component\HttpFoundation\File\UploadedFile as SymfonyUploadedFile;

/**
 * Class ImagineGenerator
 * @package Mnv\Core\Imagine\Action
 */
class ImagineGenerator extends AbstractImagineGenerator implements ActionInterface
{

    /** @var ImageInterface $image */
    private ImageInterface $image;

    /** @var array|false[]|int[]  */
    private $options;

    /** @var string $tmp */
    private string $tmp;

    /** @var array $fontOptions */
    private array $fontOptions = [];

    public function __construct(string $realPath, string $path, int $managerId)
    {

        parent::__construct($realPath,  $path, $managerId);

        $driver = $this->setDriver();
        BaseImage::setImagine($driver);
    }

    /**
     *
     * @param SymfonyUploadedFile $file
     * @return $this
     */
    public function init(SymfonyUploadedFile $file): ImagineGenerator
    {
        $this->file = $file;
        $this->generatorExtension($file->getClientOriginalExtension());

        /** сбор опций обработки `watermark` $this->fontOptions = [
         * 'Размер шрифта (size)'        => 'watermark_font',
         * 'Цвет шрифта (color)'         => 'watermarkColor',
         * 'Прозрачность шрифта (alpha)' => 'watermark_opacity',  // пока не работает
         * 'Поворот текста (angle)'      => 'watermark_rotate'
         * ];
         */
        $this->fontOptions = [
            'size'      => Config::getValue('watermark_font'),
            'color'     => [
                'light' => Config::getValue('watermark_color_light'),
                'dark'  => Config::getValue('watermark_color_dark')
            ],
            'alpha'     => intval(Config::getValue('watermark_opacity')),
            'angle'     => Config::getValue('watermark_rotate'),
            'margin'    => 20,
        ];

        try {
            $this->options = BaseImage::mergeOptions($this->extension, Config::getValue('thumbnail_quality'));
        } catch (InvalidParamException $e) {
            print $e->getMessage();
        }

        /** название файла */
        if (Config::getValue('keep_original_image_name'))
            $this->codeImage = pregGetValue('/([^\/]+)\.[^\.]+$/', $this->file->getClientOriginalName());
        if (empty($this->codeImage))
            $this->codeImage = substr(md5(number_format(time() * rand(),0,'','')),3,12);

        /** получение временного файла */
        $this->tmp = $this->file->getPathname();

        /** достаем временный файл для обработки */
        try {
            $this->image = BaseImage::open($this->tmp);
        } catch (InvalidParamException $e) {
            print $e->getMessage();
        }

        return $this;
    }

    /**
     * @return bool|int|string|null
     */
    public function save()
    {
        $images = [
            'name'      => $this->codeImage . '.' . $this->extension,
            'size'      => $this->file->getSize() ?? null,
            'mimeType'  => $this->file->getClientMimeType(),
        ];

        $this->resizeImage($this->image->getSize()->getWidth(), $this->image->getSize()->getHeight(), $this->realPath . $this->codeImage . '.' . $this->extension);

        foreach ($this->sizes as $size) {
            $sizes = $this->autoSize(Config::getValue($size . '_thumb'));
            $this->resizeImage($sizes[0], $sizes[1], $this->realPath  . $size . '/' . $this->codeImage . '.' . $this->extension);
        }

        return $this->saveFile($images);
    }

    /**
     * обработка и сохранение размеров
     *
     * @param int $width
     * @param int $height
     * @param $path
     */
    public function resizeImage(int $width, int $height, $path)
    {
        try {
            if (Config::getValue('allow_watermark') && $this->extension != 'gif') {
                BaseImage::textBox($this->tmp, Config::getValue('watermark_text'), $this->fontWatermark, Config::getValue('watermark_position'), $this->fontOptions)->thumbnail(new Box($width, $height))->save($path, $this->options);
            } else {
                BaseImage::resize($this->tmp, $width, $height)->save($path, $this->options);
            }
        } catch (InvalidParamException $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Получить драйвер обработчика файла
     */
    private function setDriver(): ImagineInterface
    {

        if (Config::getValue('image_library') != 2) {
            if (extension_loaded('imagick') && class_exists('Imagick'))	{
                $this->driver = 'imagick';

                if (!\Imagick::queryFormats('WEBP') && function_exists('imagewebp') && Config::getValue('image_library') != 1 ) {
                    $this->driver = 'gd';
                }
            }
        }

        if ($this->driver == 'imagick') {
            return new \Imagine\Imagick\Imagine();
        } else if ($this->driver == 'gd') {
            return new \Imagine\Gd\Imagine();
        } else if ($this->driver == 'gmagick') {
            return new \Imagine\Gmagick\Imagine();
        }
    }


}