<?php

namespace Src\Modules\JsonObjects\Application;

use Illuminate\Http\UploadedFile;
use Intervention\Image\ImageManager;

class FilesBrowser {

    const UPLOAD_DIR = 'uploads';

    public function upload($data)
    {
        $path = (string) $data['path'];
        $source = $data['source'];
        /** @var UploadedFile[] $files */
        $files = $data['files'];
        $resultFiles = [];
        $isImages = [];
        foreach ($files as $file){
            $mime = $file->getMimeType();
            if(substr($mime, 0, 5) == 'image') {
                $fileName = $file->getClientOriginalName();
                $resultFiles[] = $fileName;
                $isImages[] = true;
                $this->createThumb($path, $fileName, $file);
                $storagePath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path);
                $file->move($storagePath, $fileName);
            }
        }
        return [
            'data' => [
                'baseurl' => '/'.FilesBrowser::UPLOAD_DIR.'/',
                'code' => 220,
                'files' => $resultFiles,
                'isImages' => $isImages,
                'messages' => [],
            ],
            'elapsedTime' => null,
            'success' => true,
            'time' => date('Y-m-d H:i:s'),
        ];
    }

    private function createThumb($path, $fileName, UploadedFile $file)
    {
        $originalPath = $file->getRealPath();
        $img = (new ImageManager())->make($originalPath);
        $resizedImg = $img->resize(200, 200, function ($constraint) {
            $constraint->aspectRatio();
        });
        $storagePath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path . '/_thumb');
        $resizedImg->save($storagePath . '/' . $fileName);
    }

    public function create($data)
    {
        $path = (string) $data['path'];
        $source = $data['source'];
        $name = $data['name'];
        $storagePath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path);
        if(!file_exists($storagePath . $name) && mkdir($storagePath . '/' . $name) && mkdir($storagePath . '/' . $name . '/_thumb')){
            $result = [
                'data' => [
                    'messages' => [
                        'Directory successfully created',
                    ],
                    'code' => 220,
                ],
                'success' => true,
                'time' => date('Y-m-d H:i:s'),
            ];
        }else{
            $result = [
                'data' => [
                    'messages' => [
                        'Directory already exists',
                    ],
                    'code' => 406,
                ],
                'success' => false,
                'time' => date('Y-m-d H:i:s'),
            ];
        }
        return $result;
    }

    public function move($data)
    {

    }

    public function remove($data)
    {

    }

    public function items($data)
    {
        $path = (string) $data['path'];
        // $sources = $data['source'] ?? 0;
        $storagePath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path);
        // try {
            $list = scandir($storagePath);
        // }catch(\Throwable $e){
        //     $list = [];
        // }
        
        $files = array_values(array_filter($list, function($item) use ($storagePath) {
            return is_file($storagePath . '/' . $item) && mb_substr($item, 0, 1) != '.';
        }));
        $filesData = array_map(function ($file) use ($storagePath) {
            return [
                'changed' => '03/02/2020 10:40 AM',
                'file' => $file,
                'isImage' => true,
                'size' => round(filesize($storagePath . '/' . $file) / 1024, 2) . 'kB',
                'thumb' => '_thumb/' . $file,
            ];
        }, $files);
        return [
            'data' => [
                'code' => 220,
                'sources' => [
                    [
                        'baseurl' => '/'.FilesBrowser::UPLOAD_DIR.'/',
                        'path' => $path,
                        'files' => $filesData,
                        'name' => 'default',
                    ],
                ],
            ],
            'success' => true,
            'time' => date('Y-m-d H:i:s'),
        ];
    }

    public function folder($data)
    {
        $path = (string) $data['path'];
        // $sources = $data['source'] ?? 0;
        $storagePath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path);
        $list = scandir($storagePath);
        $dirs = array_values(array_filter($list, function($item) use ($storagePath) {
            return is_dir($storagePath . '/' . $item) && $item != '_thumb';
        }));
        return [
            'data' => [
                'code' => 220,
                'sources' => [
                    [
                        'baseurl' => '/'.FilesBrowser::UPLOAD_DIR.'/',
                        'path' => $path,
                        'folders' => $dirs,
                        'name' => 'default',
                    ],
                ],
            ],
            'success' => true,
            'time' => '2020-03-02 10:53:50',
        ];
    }

    public function tree($data)
    {

    }

    public function getPermissions()
    {
        return [
            'data' => [
                'code' => 220,
                'permissions' => [
                    'allowFileMove' => false,
                    'allowFileRemove' => true,
                    'allowFileRename' => false,
                    'allowFileUpload' => true,
                    'allowFileUploadRemote' => true,
                    'allowFiles' => true,
                    'allowFolderCreate' => true,
                    'allowFolderMove' => false,
                    'allowFolderRemove' => true,
                    'allowFolderRename' => true,
                    'allowFolders' => true,
                    'allowImageCrop' => false,
                    'allowImageResize' => false,
                ],
            ],
            'success' => true,
            'time' => date('Y-m-d H:i:s'),
        ];
    }

    public function folderRemove($data)
    {
        $path = $data['path'];
        $name = $data['name'];
        $storagePath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path . '/' . $name);
        $this->rmdir_recursive($storagePath);
        $result = [
            'data' => [
                'messages' => [
                    'Directory successfully deleted',
                ],
                'code' => 220,
            ],
            'success' => true,
            'time' => date('Y-m-d H:i:s'),
        ];

        return $result;
    }

    private function rmdir_recursive($dir) {
        foreach(scandir($dir) as $file) {
            if ('.' === $file || '..' === $file) continue;
            if (is_dir("$dir/$file")) $this->rmdir_recursive("$dir/$file");
            else unlink("$dir/$file");
        }
        rmdir($dir);
    }

    public function folderRename($data)
    {
        $path = $data['path'];
        $name = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path . '/' . $data['name']);
        $newName = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path . '/' . $data['newname']);

        rename($name, $newName);

        $result = [
            'data' => [
                'messages' => [
                    'Directory successfully renamed',
                ],
                'code' => 220,
            ],
            'success' => true,
            'time' => date('Y-m-d H:i:s'),
        ];

        return $result;
    }

    public function fileRemove($data)
    {
        $path = (string) $data['path'];
        $name = $data['name'];

        $storagePath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path . '/' . $name);
        unlink($storagePath);
        $thumbPath = storage_path(FilesBrowser::UPLOAD_DIR . '/' . $path . '/_thumb/' . $name);
        unlink($thumbPath);

        $result = [
            'data' => [
                'messages' => [
                    'File successfully removed',
                ],
                'code' => 220,
            ],
            'success' => true,
            'time' => date('Y-m-d H:i:s'),
        ];

        return $result;
    }

}
