<?php

class ControllerCommonUpload extends Controller
{

    private $pathFile;
    private $pathValidate;
    private $allowed = array();
    private $allowedExt = array();
    private $linkFile;
    private $folder;

    public $allowedImg = array();
    public $allowedImgExt = array();

    public $allowedRecord = array();
    public $allowedRecordExt = array();


    public function __construct($registry)
    {
        parent::__construct($registry);

        $this->allowedImg = array_values(Type_ImgAllowed::getEnumList());
        $this->allowedImgExt = array_keys(Type_ImgAllowed::getEnumList());

        $this->allowedRecord = array_values(Type_RecordAllowed::getEnumList());
        $this->allowedRecordExt = array_keys(Type_RecordAllowed::getEnumList());

        $this->data['Type_ImageUpload'] = Type_ImageUpload::getTypeForJs();
        $this->template = 'common/filemanager.twig';

    }

    public function getFolder()
    {
        return $this->folder;
    }

    public function setFolder($folder)
    {
        $this->folder = $folder;
    }

    public function getLinkFile()
    {
        return $this->linkFile;
    }

    public function setLinkFile($linkFile)
    {
        $this->linkFile = $linkFile;
    }

    public function getPathFile()
    {
        return $this->pathFile;
    }

    public function setPathFile($pathFile)
    {
        $this->pathFile = $pathFile;
    }

    public function getPathValidate()
    {
        return $this->pathValidate;
    }

    public function setPathValidate($pathValidate)
    {
        $this->pathValidate = $pathValidate;
    }

    public function getAllowed()
    {
        return $this->allowed;
    }

    public function setAllowed($allowed)
    {
        $this->allowed = $allowed;
    }

    public function getAllowedExt()
    {
        return $this->allowedExt;
    }

    public function getDirectory()
    {
        $directory = '/';

        if (isset($this->request->post['directory'])) {
            $directory = str_replace('../', '', $this->request->post['directory']);
        }

        $directory = rtrim($this->getPathFile() . 'data/' . $directory);
        $directory = str_replace('//', '/', $directory);

        return $directory;
    }

    public function getFiles()
    {
        $this->load->dmodel('tool/image');
        $this->load->type('tipocomum');

        $json = array();
        $directory = $this->getDirectory();

        // $allowedExtensions = ['.jpeg', '.jpg', '.png', '.gif', '.pdf'];
        $allowedExtensions = $this->getAllowedExt();

        $files = glob(rtrim($directory, '/') . '/*');

        if ($files) {
            foreach ($files as $file) {
                if (is_file($file)) {
                    $ext = strrchr($file, '.');
                } else {
                    $ext = '';
                }

                if (in_array(strtolower($ext), $allowedExtensions)) {
                    $size = filesize($file);

                    $i = 0;

                    $suffix = array('B','KB','MB','GB');

                    while (($size / 1024) > 1) {
                        $size = $size / 1024;
                        $i++;
                    }

                    $thumbnail = '';
                    $dimentions = [
                        '',
                        ''
                    ];

                    if ($ext != '.pdf') {
                        $thumbnailImage = basename($file)
                            ? utf8_substr($file, utf8_strlen($this->getPathFile()))
                            : 'no_image.jpg';

                        $thumbnail = $this->dmodel_tool_image->resize(
                            $thumbnailImage,
                            Type_MiniatureMedium::Tp_width,
                            Type_MiniatureMedium::Tp_height
                        );

                        $dimentions = getimagesize($file);
                    }


                    $json[] = array(
                        'filename' => basename($file),
                        'thumbnail' => $thumbnail,
                        'file' => utf8_substr($file, utf8_strlen($this->getPathFile() . 'data/')),
                        'size' => round(utf8_substr($size, 0, utf8_strpos($size, '.') + 4), 2) . $suffix[$i],
                        'ext' => strrchr(basename($file), '.'),
                        'width' => $dimentions[0],
                        'height' => $dimentions[1],
                        'linkdireto' => $this->getLinkFile() . utf8_substr($file, utf8_strlen($this->getPathFile() . 'data/')),
                    );
                }
            }
        }

        return $json;
    }

    public function setAllowedExt($allowedExt)
    {
        $this->allowedExt = $allowedExt;
    }

    public function directories()
    {
        $response = array();

        $directories = glob($this->getDirectory() . '/*', GLOB_ONLYDIR);

        if ($directories) {
            $i = 0;

            foreach ($directories as $directory) {
                if (basename($directory) === 'eftr') {
                    continue;
                }
                $response[$i]['data'] = basename($directory);
                $response[$i]['attributes']['directory'] = utf8_substr($directory, strlen($this->getPathFile() . 'data/'));

                $children = glob(rtrim($directory, '/') . '/*', GLOB_ONLYDIR);

                if ($children) {
                    $response[$i]['children'] = ' ';
                }

                $i++;
            }
        }


        return $response;
    }

    public function directory()
    {
        $responseEncoded = json_encode($this->directories());
        $this->response->setOutput($responseEncoded);
    }

    public function loadFolders()
    {
        $response = [];

        $response['folders'] = $this->directories();
        $response['files'] = $this->getFiles();

        $this->response->setOutput(json_encode($response));
    }

    public function files()
    {
        $files = $this->getFiles();
        $this->response->setOutputJson($files);
    }

    public function create()
    {
        $this->language->load('common/filemanager');

        $json = array();

        if (isset($this->request->post['name']) || $this->request->post['name']) {
            $directory = $this->getDirectory();

            if (!is_dir($directory)) {
                $json['error'] = $this->language->get('error_directory');
            }

            if (file_exists($directory . '/' . str_replace('../', '', $this->request->post['name']))) {
                $json['error'] = $this->language->get('error_exists');
            }
        } else {
            $json['error'] = $this->language->get('error_name');
        }

        if (!$this->user->hasPermission('modify', $this->getPathValidate())) {
            $json['error'] = $this->language->get('error_permission');
        }

        if (!isset($json['error'])) {
            mkdir($directory . '/' . str_replace('../', '', $this->request->post['name']), 0777);

            $json['success'] = $this->language->get('text_create');
            $json['directories'] = $this->directories();
        }

        $this->response->setOutputJson($json);
    }

    public function deleteFiles()
    {
        $this->language->load('common/filemanager');

        $response = [];

        if (!$this->user->hasPermission('modify', $this->getPathValidate())) {
            $response['error'] = $this->language->get('error_permission');
            return $this->response->setOutputJson($response);
        }

        $files = $this->request->post['files'];

        if (!isset($files)) {
            $response['error'] = $this->language->get('error_select');
            return $this->response->setOutputJson($response);
        }

        if (!is_array($files)) {
            $files = [];
            $files[] = $this->request->post['files'];
        }

        foreach ($files as $fileKey => $fileValue) {
            $filePath = rtrim(
                $this->getPathFile() . 'data/' .
                str_replace('../', '',
                    html_entity_decode($fileValue, ENT_QUOTES, 'UTF-8')
                ), '/'
            );

            if (file_exists($filePath)) {
                unlink($filePath);
            }
        }

        $response = [
            'success' => $this->language->get('text_delete'),
            'files' => $this->getFiles(),
        ];

        $this->response->setOutputJson($response);
    }

    public function delete()
    {
        $this->language->load('common/filemanager');

        $json = array();

        if (isset($this->request->post['path'])) {
            $path = rtrim($this->getPathFile() . 'data/' . str_replace('../', '', html_entity_decode($this->request->post['path'], ENT_QUOTES, 'UTF-8')), '/');

            if (!file_exists($path)) {
                $json['error'] = $this->language->get('error_select');
            }

            if ($path == rtrim($this->getPathFile() . 'data/', '/')) {
                $json['error'] = $this->language->get('error_delete');
            }
        } else {
            $json['error'] = $this->language->get('error_select');
        }

        if (!$this->user->hasPermission('modify', $this->getPathValidate())) {
            $json['error'] = $this->language->get('error_permission');
        }

        if (!isset($json['error'])) {
            if (is_file($path)) {
                unlink($path);
            } elseif (is_dir($path)) {
                $files = array();

                $path = array($path . '*');

                while (count($path) != 0) {
                    $next = array_shift($path);

                    foreach (glob($next) as $file) {
                        if (is_dir($file)) {
                            $path[] = $file . '/*';
                        }

                        $files[] = $file;
                    }
                }

                rsort($files);

                foreach ($files as $file) {
                    if (is_file($file)) {
                        unlink($file);
                    } elseif (is_dir($file)) {
                        rmdir($file);
                    }
                }
            }

            $json['success'] = $this->language->get('text_delete');
            $json['folders'] = $this->directories();
            $json['files'] = $this->getFiles();
        }

        $this->response->setOutputJson($json);
    }

    public function move()
    {
        $this->language->load('common/filemanager');

        $response = array();

        $from = $this->request->post['from'];
        $to = $this->request->post['to'];

        if (!isset($from) || !isset($to)) {
            $response['error'] = $this->language->get('error_directory');
            return $this->response->setOutputJson($response);
        }

        if (!$this->user->hasPermission('modify', $this->getPathValidate())) {
            $response['error'] = $this->language->get('error_permission');
            return $this->response->setOutputJson($response);
        }

        if (!is_array($from)) {
            $from = [];
            $from[] = $this->request->post['from'];
        }

        foreach ($from as $fromKey => $fromValue) {
            $fromPath = rtrim($this->getPathFile() . 'data/' . str_replace('../', '', html_entity_decode($fromValue, ENT_QUOTES, 'UTF-8')), '/');

            if (!file_exists($fromPath)) {
                $response['error'] = $this->language->get('error_missing');
                break;
            }

            if ($fromPath == $this->getPathFile() . 'data') {
                $response['error'] = $this->language->get('error_default');
                break;
            }

            $toPath = rtrim($this->getPathFile() . 'data/' . str_replace('../', '', html_entity_decode($to, ENT_QUOTES, 'UTF-8')), '/');
            $toPath = str_replace('//', '/', $toPath);


            if (!file_exists($toPath)) {
                $response['error'] = $this->language->get('error_move');
                break;
            }

            if (!file_exists($toPath . '/' . basename($fromPath))) {
                rename($fromPath, $toPath . '/' . basename($fromPath));
            }
        }

        $response['files'] = $this->getFiles();
        if (!isset($response['error'])) {
            $response['success'] = $this->language->get('text_move');
        }

        $this->response->setOutputJson($response);
    }

    public function copy()
    {
        $this->language->load('common/filemanager');

        $json = array();

        if (isset($this->request->post['path']) && isset($this->request->post['name'])) {
            if ((utf8_strlen($this->request->post['name']) < 3) || (utf8_strlen($this->request->post['name']) > 255)) {
                $json['error'] = $this->language->get('error_filename');
            }

            $old_name = rtrim($this->getPathFile() . 'data/' . str_replace('../', '', html_entity_decode($this->request->post['path'], ENT_QUOTES, 'UTF-8')), '/');

            if (!file_exists($old_name) || $old_name == $this->getPathFile() . 'data') {
                $json['error'] = $this->language->get('error_copy');
            }

            if (is_file($old_name)) {
                $ext = strrchr($old_name, '.');
            } else {
                $ext = '';
            }

            $new_name = dirname($old_name) . '/' . str_replace('../', '', html_entity_decode($this->request->post['name'], ENT_QUOTES, 'UTF-8') . $ext);

            if (file_exists($new_name)) {
                $json['error'] = $this->language->get('error_exists');
            }
        } else {
            $json['error'] = $this->language->get('error_select');
        }

        if (!$this->user->hasPermission('modify', $this->getPathValidate())) {
            $json['error'] = $this->language->get('error_permission');
        }

        if (!isset($json['error'])) {
            if (is_file($old_name)) {
                copy($old_name, $new_name);
            } else {
                $this->recursiveCopy($old_name, $new_name);
            }

            $json['success'] = $this->language->get('text_copy');
        }

        $this->response->setOutputJson($json);
    }

    public function recursiveCopy($source, $destination)
    {
        $directory = opendir($source);

        @mkdir($destination);

        while (false !== ($file = readdir($directory))) {
            if (($file != '.') && ($file != '..')) {
                if (is_dir($source . '/' . $file)) {
                    $this->recursiveCopy($source . '/' . $file, $destination . '/' . $file);
                } else {
                    copy($source . '/' . $file, $destination . '/' . $file);
                }
            }
        }

        closedir($directory);
    }

    public function folders()
    {
        $this->response->setOutput($this->recursiveFolders($this->getPathFile() . 'data/'));
    }

    protected function recursiveFolders($directory)
    {
        $output = '';

        $output .= '<option value="' . utf8_substr($directory, strlen($this->getPathFile() . 'data/')) . '">' . utf8_substr($directory, strlen($this->getPathFile() . 'data/')) . '</option>';

        $directories = glob(rtrim(str_replace('../', '', $directory), '/') . '/*', GLOB_ONLYDIR);

        foreach ($directories as $directory) {
            $output .= $this->recursiveFolders($directory);
        }

        return $output;
    }

    public function rename()
    {
        $this->language->load('common/filemanager');

        $json = array();

        if (isset($this->request->post['path']) && isset($this->request->post['name'])) {
            if ((utf8_strlen($this->request->post['name']) < 3) || (utf8_strlen($this->request->post['name']) > 255)) {
                $json['error'] = $this->language->get('error_filename');
            }

            $old_name = rtrim($this->getPathFile() . 'data/' . str_replace('../', '', html_entity_decode($this->request->post['path'], ENT_QUOTES, 'UTF-8')), '/');

            if (!file_exists($old_name) || $old_name == $this->getPathFile() . 'data') {
                $json['error'] = $this->language->get('error_rename');
            }

            if (is_file($old_name)) {
                $ext = strrchr($old_name, '.');
            } else {
                $ext = '';
            }

            $new_name = dirname($old_name) . '/' . str_replace('../', '', html_entity_decode($this->request->post['name'], ENT_QUOTES, 'UTF-8') . $ext);

            if (file_exists($new_name)) {
                $json['error'] = $this->language->get('error_exists');
            }
        }

        if (!$this->user->hasPermission('modify', $this->getPathValidate())) {
            $json['error'] = $this->language->get('error_permission');
        }

        if (!isset($json['error'])) {
            rename($old_name, $new_name);

            $json['success'] = $this->language->get('text_rename');
            $json['folders'] = $this->directories();
            if (!is_file($new_name)) {
                $this->request->post['directory'] = '/' . $this->request->post['name'];
            }
            $json['files'] = $this->getFiles();
        }

        $this->response->setOutputJson($json);
    }

    public function sendFiles() {
        $this->language->load('common/filemanager');

        $response = [];

        $directory =  $this->getDirectory();
        $files = $this->request->post['files'];
        $names = $this->request->post['names'];

        foreach ($files as $key_file => $value_file) {
            $filename = $names[$key_file];

            $exploded_file = explode(',', $value_file);
            $mime = str_replace(['data:', ';base64'], '', $exploded_file[0]);

            $decoded_file = base64_decode($exploded_file[1]);
            $dimensions_file = getimagesizefromstring($decoded_file);
            $extension_file = explode('/', $mime);
            $extension_file = $extension_file[1] === 'jpeg' ? 'jpg' : $extension_file[1];

            if($dimensions_file && ($dimensions_file[0] > 1920 || $dimensions_file[1] > 1920)){
                $response['error'][$filename] = 'Imagem muito grande, a largura e a altura máxima é de 1920px';
            }

            $output_file = $directory . '/' . $filename . '.' . $extension_file;

            $open_file = fopen($output_file, "wb");
            fwrite($open_file, $decoded_file);
            fclose($open_file);
        }

        $response['success'] = $this->language->get('text_uploaded');
        $response['files'] = $this->getFiles();

        return $this->response->setOutput(json_encode($response));
    }
}
