<?php

namespace App\Classes\Modules\Documents\Services;

use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\Documents\DataTransferObjects\FileObject;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;

class ConvertsBase64ToFile
{

    /** @var string|null */
    private $path;

    /** @var array */
    private $filesInfo;

    /**
     * ConvertsBase64ToFile constructor.
     * @param null|string $path
     */
    public function __construct(?string $path = 'documents')
    {
        $this->path = $path;
        $this->filesInfo = [];
    }


    /**
     * @param array $files
     * @return array
     * @throws MalformedRequestException
     */
    public function convert($files = []){
        foreach ($files as $file) {

            $object = new FileObject($file);
            $object->getExtension() === 'pdf' ? $this->generatePDF($object) : $this->generateImage($object);

        }

        return $this->filesInfo;

    }

    /**
     * @param FileObject $file
     * @throws MalformedRequestException
     */
    private function generatePDF(FileObject $file){

        $filePath = $this->generateFile($file);
        $this->updateFiles($file, [ 'original' => [ 'file' => $filePath ] ]);
    }

    /**
     * @param FileObject $file
     * @throws MalformedRequestException
     */
    private function generateImage(FileObject $file){

        $fileInfo = [];

        foreach (['original' => null, 'large' => 800, 'medium' => 480, 'small' => 320] as $size => $value) {
            $suffix = $size !== 'original' ? '_'.$size : '';

            if($size !== 'original') {
                $thumbnail = $file->getData()->widen($value, function ($constraint) {

                    $constraint->upsize();

                })->heighten($value, function ($constraint) {

                    $constraint->upsize();

                });

                $file->setData($thumbnail->encode('data-url')->encoded);
            }


            $filePath = $this->generateFile($file, $suffix);

            $fileInfo[] = [ $size => [ 'file' => $filePath, 'width' => $file->getData()->width(), 'height' => $file->getData()->height() ]];


        }

        $this->updateFiles($file, $fileInfo);

    }

    /**
     * @param FileObject $file
     * @param string $suffix
     * @return string
     * @throws MalformedRequestException
     */
    private function generateFile(FileObject $file, string $suffix = '') {

        $filePath = $this->path.'/'.$file->getFileName().$suffix.'.'.$file->getExtension();

        Storage::disk('documents')->put($filePath, $file->getDecodedData());

        return $filePath;

    }

    /**
     * @param FileObject $file
     * @param array $fileInfo
     * @throws MalformedRequestException
     */
    private function updateFiles(FileObject $file, array $fileInfo){
        $this->filesInfo[] = json_encode([
            'path' => $this->path,
            'filename' => $file->getFileName().'.'.$file->getExtension(),
            'mime_type' => $file->getMimeType(),
            'extension' => $file->getExtension(),
            'file_info' => $fileInfo
        ]);
    }

}