<?php
/**
 * File manager cals
 */
class FileManager{

    /**
     * upload new files
     * @param  file $file           file to be uploaded
     * @param  String $documentType type of the document
     * @param  String $documentName name of the document
     * @param  INT    $uploadedBy   who uploaded the document, if not set the loged in user will be
     * @param  INT    $owner        document owner
     * @return Array                upload message
     */
    public function uploadFile($file, $idDocumentType, $documentName, $uploadedBy = 0, $owner = 0, $visibleToCustomer = 1){
        global $database, $user;
        $data = [];
        $documentName = $database->escapeValue($documentName);
        $idDocumentType = $database->escapeValue($idDocumentType);
        $visibleToCustomer = isset($visibleToCustomer) ? $database->escapeValue($visibleToCustomer) : 1;

        if(empty($file)){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'NO_FILE'
            ];

            return $data;
        }

        $tmpName = $file['tmp_name'];
        $ext = explode('.',$file['name']);
        $ext = end($ext);
        $errorCode = $file['error'];

        if($errorCode !== 0){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'UPLOAD_ERROR'
            ];

            return $data;
        }

        if(!$uploadedBy){
            $uploadedBy = $user->getUserId();
        }

        if(!$owner){
            $owner = "null";
        }
        $sql = "SELECT dt.id AS idDocumentType, dt.folderName
                FROM ".TABLES['document_types']." dt
                WHERE id=$idDocumentType";
        $query = $database->query($sql);
        if($database->numRows($query) !== 1){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'INVALID_DOCUMENT_TYPE'
            ];

            return $data;
        }
        $documentType = $database->fetchArray($query);

        $timestamp = time() . '_'. rand(1000,9999);
        $documentPath = $documentType['folderName'].'/'.$timestamp. '.' .$ext;
        $documentFullPath = PATH_UPLOAD.$documentPath;
        $sql = "INSERT INTO ".TABLES['documents']."
                (uploadedBy, idOwner, idDocumentType, documentName, documentPath, extension, visibleToCustomer)
                VALUES($uploadedBy, $owner,'".$documentType['idDocumentType']."', '$documentName', '$documentPath', '$ext', $visibleToCustomer)";
        $query = $database->query($sql);
        $idDocument = $database->getInsertId();
        $saveStatus = move_uploaded_file( $tmpName , $documentFullPath );
        if(!$saveStatus || $database->affectedRows() === 0){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'UPLOAD_ERROR'
            ];

            return $data;
        }

        $data['idDocument'] = $idDocument;

        return $data;
    }

    /**
     * update an existing document
     * @param  INT $idDocument id of the document
     * @param  file $file      file to be uploaded
     * @return Array           Array with document id in case of success or error messages
     */
    public function updateDocument($idDocument, $file, $documentName = ''){
        global $database, $user;
        $data = [];
        $idDocument = $database->escapeValue($idDocument);
        $extraField = '';

        if(empty($file)){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'WRONG_FILE_TYPE'
            ];

            return $data;
        }

        $sql = "SELECT d.documentPath
                FROM ".TABLES['documents']." d
                WHERE d.id=$idDocument
                LIMIT 1";
        $query = $database->query($sql);
        if($database->numRows($query) !== 1){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'FILE_NOT_EXISTS'
            ];

            return $data;
        }

        $oldFile = $database->fetchArray($query);
        $tmpName = $file['tmp_name'];
        $ext = explode('.',$file['name']);
        $ext = end($ext);
        $errorCode = $file['error'];

        if($errorCode !== 0){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'UPLOAD_ERROR'
            ];

            return $data;
        }

        $documentPath = $oldFile['documentPath'];
        $documentFullPath = PATH_UPLOAD.$documentPath;
        $del_status = unlink($documentFullPath);
        $saveStatus = move_uploaded_file($tmpName, $documentFullPath);

        if(!$saveStatus){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'UPLOAD_ERROR'
            ];

            return $data;
        }

        if($documentName) {
            $extraField = ", documentName='".$documentName."'";
        }

        $sql = "
                UPDATE ".TABLES['documents']."
                    SET extension='".$ext."'
                    $extraField
                WHERE id=$idDocument";
        $query = $database->query($sql);

        $data['idDocument'] = $idDocument;

        return $data;
    }

    /**
     * download an existing file
     * @param  String $filePath path of the file
     * @param  String $fileName the name of the document after download
     * @return octet-stream     file to be downloaded
     */
    public function downloadFile($idDocument, $fileName, $fileType=''){
        global $database, $user;
        $whereSql = "";
        $userType = $user->getUserType();

        if($userType !== USER_TYPES['BROKER'] && $fileType !== 'installationProtocol'){
            if($userType === USER_TYPES['CUSTOMER']) {
                $whereSql = "AND d.visibleToCustomer = 1";
            } else {
                $whereSql = "AND ( d.uploadedBy=".$user->getUserId()." OR d.uploadedBy IS NULL )";
            }
        }

        $sql = "SELECT d.documentPath
                FROM ".TABLES['documents']." d
                WHERE d.id=$idDocument $whereSql";
        $query = $database->query($sql);
        if($database->numRows($query) !== 1){
            trigger_error("Invalid document!", E_USER_ERROR);
        }

        $document = $database->fetchArray($query);

        header('Content-Disposition: attachment;filename="'.$fileName.'"');
        header('Content-Type: application/octet-stream');
        ob_start();
        require(PATH_UPLOAD . $document['documentPath']);

        return ob_get_clean();
    }

    /**
     * add a new type for a document
     * @param String $documentNewType name for the new document type
     */
    public function addNewDocumnetType($documentNewType){
        global $database;
        $documentNewType = $database->escapeValue($documentNewType);

        if(!$documentNewType){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'NO_TYPE_FOR_NEW'
            ];

            return $data;
        }

        $folderName = '';
        $folderNamePieces = explode(' ',$documentNewType);
        foreach ($folderNamePieces as $key => $value) {
            $folderName .= $key === 0 ? $value : ucfirst($value) ;
        }
        $folderFullName = PATH_UPLOAD.$folderName;
        if (file_exists($folderFullName)){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'TYPE_EXISTS'
            ];

            return $data;
        }

        $createNewDir = mkdir($folderFullName, 0777);

        if(!$createNewDir){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'MKDIR_ERROR'
            ];

            return $data;
        }

        $sql = "INSERT INTO ".TABLES['document_types']."
               (type, folderName)
               VALUES('$documentNewType', '$folderName')";
        $query = $database->query($sql);

        if($database->affectedRows() > 0){
            $data['messages'][] = [
                'code' => 'success',
                'message' => 'NEW_TYPE_ADDED'
            ];
        }else{
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'ERROR_NEW_TYPE'
            ];
        }

        return $data;
    }

    /**
     * remove documents
     * @param  INT $idDocument id for the document
     * @return Array           delete message
     */
    public function removeDocument($idDocument){
        global $database;

        if(!$idDocument){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'NO_SELECTION_FOR_REMOVE'
            ];
        }

        $sql = "SELECT d.documentPath
                FROM ".TABLES['documents']." d
                WHERE d.id=$idDocument
                LIMIT 1";
        $query = $database->query($sql);
        if($database->numRows($query) !== 1){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'FILE_NOT_EXISTS'
            ];

            return $data;
        }

        $documentPath = $database->fetchArray($query);
        $documentFullPath = PATH_UPLOAD.$documentPath['documentPath'];

        $del_status = unlink($documentFullPath);

        if(!$del_status){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'UNABLE_TO_DELETE'
            ];

            return $data;
        }

        $sqlDelete = "DELETE FROM ".TABLES['documents']."
                      WHERE id=$idDocument";
        $query = $database->query($sqlDelete);
        $documentsDeleted = $database->affectedRows();

        if($documentsDeleted > 0){
            $data['messages'][] = [
                'code' => 'success',
                'message' => 'DOCUMENT_DELETED'
            ];
        }else{
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'UNABLE_TO_DELETE'
            ];
        }

        return $data;
    }

}
