/* eslint-disable no-console */
/*
 Used as a router for Uploads Providers
 */
'use strict';
//local libs
const UtilHttpStatus = require('../../shared/utils/UtilHttpStatus');
const UtilDocumentId = require('../../shared/utils/UtilDocumentId');
const UtilFileReference = require('../utils/UtilFileReference');
const UtilError = require('../utils/UtilError');
const UtilFileUploadData = require('../utils/UtilFileUploadData');
const UtilPackage = require('../utils/UtilPackage');
const { upload, getSubDirectory } = require('../file/FileSettings');
const UtilUploads = require('../../shared/utils/UtilUploads');

//globals
const provider = require('../uploads/providers/PlainDirectoryProvider');
var mime = require('mime-types');


exports.uploadFiles = async function (req, res) {

    let fileInfo;
    if (req.body && (req.body.uploadedFile || req.body.uploaded96File )){
      const uploadInfo = {
        fileData: req.body.uploadedFile || req.body.uploaded96File,
        isImage : req.body.isImage != null ? req.body.isImage === 'true' : false,
        fileNo : req.body.fileNo,
        fileType: req.body.fileType,
        file: req.files != null ? req.files.file : null
      };
      if(!UtilFileUploadData.whiteListed(uploadInfo.fileType)){
        throw new UtilError.InvalidRequestError('File type not allowed.');
      }

      // upload file
      fileInfo = await provider.uploadFiles(uploadInfo, true);
    }

    const uploadFunc = upload.single("file");

    uploadFunc(req, res, async function (err) {
        if (err) {
            return res.status(500).send(err.message);
        }

        // if (!req.file && (!req.body || !req.body.file)) {
        //     return res.status(500).send("No file found in the request.");
        // }

        try {
            const basePath = getSubDirectory();
            const file = req.file || req.body.file || req.body;
            const fileName = file.fileName || req.body.fileName || file.originalname || req.body.originalname;
            const fileReferenceTemplateId = req.body.fileReferenceTemplateId;

            const mimetype = file.mimetype || req.body.mimetype || fileInfo.mime;
            const fileType = UtilUploads.getExtension(fileName);

            if (!UtilFileUploadData.whiteListed(fileType)) {
                throw new UtilError.InvalidRequestError('File type not allowed.');
            }

            // using 'filename' from multer response file as fileNo
            // so we won't have to rename the file on every upload
            let fileNo = file.filename || req.body.fileNo;
            if(!fileNo && fileInfo && fileInfo.fileNo){
              fileNo = fileInfo.fileNo;
            }


            //prepare data for creating file reference
            const meta = {

                file: {
                    fileNo,
                    fileName: fileName,
                    fileType: fileType,
                    basePath
                },

                parent: {//parent document id
                    documentId: req.body.documentId,
                    name: req.body.documentName
                },

                ownerUserId: req.user.documentId

            };

            if (mimetype) {
                meta.file.ext = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length);
                if(!meta.file.ext && fileInfo && fileInfo.fileNo && fileInfo.mime){
                  meta.file.ext = fileInfo.ext;
                }
                meta.file.mimeDetailsObj = {
                    contentType: mimetype
                };
            }

            //create file reference
            if (!req.body.isCreatedFileReference) {
                await UtilFileReference.createReferenceDocument(meta.file, meta.parent, meta.ownerUserId, fileReferenceTemplateId);
            }


            res.json({ fileNo, basePath, fileType });
        } catch (err) {
            logger.error('Error in file upload: ' + err.message);
            const httpStatus = err.httpStatusCode ? err.httpStatusCode : UtilHttpStatus.INTERNAL_SERVER_ERROR;
            res.status(httpStatus).send(err.message);
        }
    });
};

// req.params.fileNo
// todo: make async
exports.getFile = function(req, res){

    var fileRequest = null;

    Promise.resolve().then(function () {

        return UtilFileReference.fetchReferenceDocument(req.params.fileNo, req.user.documentId);

    }).then(function (referenceDocument) {

        if(!referenceDocument){
            throw new UtilError.NotFoundError("File not found.");
        }

        var fileFieldName = UtilFileReference.getFileFieldName();

        if(!fileFieldName){
            throw new UtilError.ServerError("Field name for files not set in fileReference configuration.");
        }else if(!referenceDocument[fileFieldName]){
            throw new UtilError.ServerError("Outdated file reference document or invalid file reference config.");
        }

        //File reference is an array because it needed to be displayed in an uploader component.
        var fileReference = referenceDocument[fileFieldName][0];

        fileRequest = {
            fileNo: req.params.fileNo,
            fileName: fileReference.fileName,
            basePath: fileReference.basePath
        };

        if(fileReference.mimeDetailsObj){
            fileRequest.mime = fileReference.mimeDetailsObj.contentType;
        }

        return new Promise(function (resolve, reject) {
            provider.getFile(fileRequest, function (err, fileInfo) {
                if(err){
                    reject(err);
                }else{
                    resolve(fileInfo);
                }
            });
        });

    }).then(function (fileInfo) {

        if(!fileInfo){
            res.status(UtilHttpStatus.INTERNAL_SERVER_ERROR).send('Upload provider did not work properly.');
            return;
        }

        //default headers
        res.setHeader('Content-Disposition', 'inline; filename=' + encodeURIComponent(fileRequest.fileName));

        //IE needs to receive the right content type to display images.
        var mime = fileRequest.mime;

        if(mime){
            res.setHeader('content-type', mime);
            res.sendFile(fileInfo.filePath);
        } else {
            //read file to get an idea of its contents; returns meta = {ext, mime}
            UtilFileUploadData.pathFileType(fileInfo.filePath, function(err, meta){

                if(!err && meta){
                    res.setHeader('content-type', meta.mime);
                }

                res.sendFile(fileInfo.filePath);

            });
        }
    }).catch(function processProviderErr(e){
        
        if(e instanceof UtilError.InvalidRequestError){
            res.status(UtilHttpStatus.BAD_REQUEST).send(e.message);
        }else if(e instanceof UtilError.NotFoundError){
            res.status(UtilHttpStatus.NOT_FOUND).send(e.message);
        }else if(e instanceof UtilError.NoPermissionError){
            res.status(UtilHttpStatus.FORBIDDEN).send(e.message);
        }else {
            res.status(UtilHttpStatus.INTERNAL_SERVER_ERROR).send(e.message);
        }

    });

};

// req.params.fid
exports.deleteFile = async function(req, res){
    var fid = req.param('fid');
    try {
        await UtilFileReference.destroyFileReference(fid, req.user.documentId);
        res.status(UtilHttpStatus.OK).send();
    }catch (err) {
        logger.error(`Failed to destroy file reference for ${fid}.`);
        logger.error(err);
        res.status(UtilHttpStatus.INTERNAL_SERVER_ERROR).send('Failed to remove file.');
    }
};

exports.provider = provider;


