    /* eslint-disable */
    import { Meteor } from 'meteor/meteor';
    import { check } from 'meteor/check';
    import Papers from './Papers';
    import Journal from '../Journal/Journal';
    import s3PublicUrl from 'node-s3-public-url';
    import SimpleSchema from 'simpl-schema';
    import rateLimit from '../../modules/rate-limit.js';
    import S3 from '../../modules/server/s3.js';
    import EmailNotification from '../../modules/server/send-email-notification.js';
    import assignPaperEditor from '../../modules/server/editorsmatter/assignPaperToEditor';
    import writePaperReview from '../../modules/server/editorsmatter/writePaperReview';
    import sendAuthorPaperReview from '../../modules/server/editorsmatter/sendAuthorPaperReview';
    import correctedPaperModule from '../../modules/server/editorsmatter/correctedPaperModule';
    import SaveArchivePaper from '../../modules/server/saveArchivePapers';
    import sendMailPdfUploaded from '../../modules/server/sendMailPdfUploaded';
    import sendEmail from '../../modules/server/send-email';
    import insertPaperModule from '../../modules/server/insertPaperModule';
    import {logger} from '../../Logger/Logger.js';
    import moment from 'moment';

    const capAllFirstLetter = ( word ) => {
      if ( word ){
        const arr = word.split(" ");
        let capWord = "";
        for (let i=0; i < arr.length; i++){
            let firstWord = arr[i];
            firstWord = firstWord.charAt(0).toUpperCase();
            let remainWord = arr[i].slice(1);
            capWord += firstWord + remainWord + " "
        }
         return capWord.trim();
      }
 
    }

  
    
    Meteor.methods({
      'papers.storepapertoAmazon': function paperMethod( paper ) {
        check( paper  ,  {
          paperId : String,
          url : String,
          name : String,
          status : String,
        });
        const sanitizedUrl =
        paper.url.replace( paper.name, `${s3PublicUrl(paper.name)}`);
        const date = (new Date()).toISOString();
        return Papers.update({ _id : paper.paperId } , {$set : {url: sanitizedUrl,
                                                          fileName: paper.name ,
                                                          status : paper.status,
                                                          date : date } });
      },
      'papers.delete': function paperMethod( paperId ) {
        check( paperId, String );
        const paper = Papers.find( {"_id" : paperId }).fetch();
        if ( paper ) {
          return S3.deleteFile(paper , () => {
            Papers.remove({ _id: paperId });
          });
        }
        throw new Meteor.Error('500', 'Must be logged in to do that!');
      },
      'papers.save': function paperMethod( paper ){
        check( paper , Object );
        return Papers.insert( paper );
      },
      'papers.update' : function paperMethod( paperId , options , editionId ){
          check(paperId , String);
          check(options , Object );
          check(editionId , String);
          const paper = Papers.findOne( paperId );
          const journal = Journal.findOne({"_id" : paper.journalID});
          const journalId = journal && journal._id
          const updatedPaper = {
            authors : options.authors,
            paperTitle : options.title,
            abstract : options.abstract,
            links : paper.pdf,
            id : paperId
         }
          //pull the previous archive paper 
          Journal.update( {"_id" : journalId, 
          "publishedEditions.editionId" : editionId } , 
          { $pull :  {"publishedEditions.$.papers" :  {"id" : paperId} }});

          Papers.update({_id : paperId} , {$set :  options  })

         return Journal.update( {"_id" : journalId,  
          "publishedEditions.editionId" : editionId } , 
          { $addToSet :  {"publishedEditions.$.papers" :  updatedPaper }})

      },

      'papers.assignPaperEditor' : function paperMethod( options ){
        check(options , Object);
        return assignPaperEditor( options ).then( (response) => {
           return response;
        }).catch( (error) => {
          throw new Meteor.Error( '500' , `${ error }`)
        })
    },

    'paper.writePaperReview' : function paperMethod( options ){
      check(options , Object);
      return writePaperReview( options ).then( (response) => {
         return response;
      }).catch( (error) => {
        throw new Meteor.Error( '500' , `${ error }`)
      })
  },

  'paper.sendReviewToAuthor' : function paperMethod( options ){
    check(options , Object);
    return sendAuthorPaperReview( options ).then( (response) => {
       return response;
    }).catch( (error) => {
      throw new Meteor.Error( '500' , `${ error }`)
    })
},

'paper.sendAuthorEditorReview' : function paperMethod( options ){
  check(options , Object);
  return correctedPaperModule( options ).then( (response) => {
     return response;
  }).catch( (error) => {
    throw new Meteor.Error( '500' , `${ error }`)
  })
},
'paper.insertPaperDetailsProxy' : function paperMethod( options ){
  check(options , Object);
  return insertPaperModule( options ).then( (response) => {
     return response;
  }).catch( (error) => {
    throw new Meteor.Error( '500' , `${ error }`)
  })
},

'papers.correctReviewEditor' : function paperMethod( paperId , reviewerId , comment){
  check(paperId , String);
  check(reviewerId , String );
  check(comment , String );
  return Papers.update({"_id" : paperId , 
                        "paperReview.reviewers.reviewerId" : reviewerId} , 
                        {$set : {"paperReview.reviewers.$.comment" : comment }});
   },


'paper.acknowledgeConfirmationPdf' : function paperMethod( paperId , succesful , paperTitle ){
  check(paperId , String);
  check(succesful , Boolean );
  check(paperTitle , String );
  
  if ( succesful ){
    return Papers.update({"_id" : paperId } , 
    {$set : {"confirmPdf.buttonClicked" : "1" ,
             "confirmPdf.pdfConfirmed" : true }});
  }
   else{
    const confirmPdf= {
      pdfDownloadLink : "",
      pdfConfirmed : "",
      confirmDate : "",
      buttonClicked : "1",
    }
    const adminEmail = Meteor.settings.private.AdminEmail;
    //send a mail to admin to reupload the pdf.
    sendEmail({ from: 'Erudite Scholars <mail@eruditescholars.net>',
    to: `${adminEmail}`,
    subject : `Check Generated PDF || ${paperTitle}`,
    template: "checkpdf-uploaded",
    templateVars: {
          paperTitle,
        },       
  })

    return Papers.update({"_id" : paperId } , 
      {$set : {"confirmPdf" : confirmPdf , 
               "pdf" : ""}});
  }

 
 },
   'papers.correctAbstract' : function paperMethod( paperId , abstract ){
    check(paperId , String);
    check(abstract , String );
  
    return Papers.update({"_id" : paperId } , 
                         {$set : {"abstract" : abstract }});
     },

   'paper.uploadDocumentByReviewer' : function paperMethod( paperObj ){
    check(paperObj , Object);
    const { paperId , url , name , date , teamId} = paperObj;
    const obj = {
      "uploadDate" : date,
      "paperUrl" : url,
      "fileName" : name,
    }
   
   return Papers.update({"_id" : paperId , "paperReview.reviewers.reviewerId" : teamId } , 
                  {$set : {"paperReview.reviewers.$.uploadedPaperUrl" : url , 
                           "paperReview.reviewers.$.uploadedFileName" : name } , 
                           $addToSet : {"paperUploads" : obj}});
      
   // return Papers.update({"_id" : paperId } , {$addToSet : {"paperUploads" : obj}});       
},

'paper.uploadDocumentByAuthor' : function paperMethod( paperObj ){
  check(paperObj , Object);
  const { paperId , url , name , date , teamId , others} = paperObj;
  //others represents the editors name 
  //teamId represents the editors email address
  const editorName = others;
  const emailAddress = teamId;
  const obj = {
    "uploadDate" : date,
    "paperUrl" : url,
    "fileName" : name,
  }
  //get the paper title using the paperId
  const paper = Papers.findOne( paperId );
  const paperTitle = paper.title;
  Papers.update({"_id" : paperId } , {$set : {"currentPaperStatus" : "04"}});
  //send a mail to chief editor here that the paper was just resubmitted
  //build the email object here
  const emailObject = {
    to : emailAddress ,
    name : editorName ,
    paperTitle,
    title : `Corrected paper titled ${paperTitle} re-uploaded.`,
    subtitle : `Re-uploaded corrected paper`,
    message : `The paper titled <b>${paperTitle} has been corrected and uploaded by the author. 
              </b>`
  }
  try{
     EmailNotification('sendMailToCheifEditorTemplate' , emailObject);
  } catch(exception){
    throw new Meteor.Error(`[500] || ${exception}`);
  }
  return Papers.update({"_id" : paperId } , {$addToSet : {"paperUploads" : obj}});       
},

'paper.uploadPdfCopy' : function paperMethod( paperObj ){
  check(paperObj , Object);
  const { paperId , url , name , date } = paperObj;
  const sanitizedUrl = url.replace( name, `${s3PublicUrl( name )}`);
 
 // Papers.update({"_id" : paperId } , {$set : {"pdfDownloadLink" : url }});
 //send an email here to the paper owner telling them to 
 //confirm the uploaded pdf copy
 //get the paper
 const paper = Papers.findOne( paperId );
 //get the uploadedBy
 const userId = paper && paper.uploadedBy;
 const user = Meteor.users.findOne( userId );
 const to = user && user.emails[0].address;
 const paperTitle = paper && capAllFirstLetter(paper.title);
 const firstName = user.profile.name.first;
 const lastName = user.profile.name.last;
 const timeStamp = new Date().toISOString();
 const urlPdfBad = Meteor.absoluteUrl(`confirm_pdf/${paperId}/${timeStamp}/conversion_failed`);
 const urlPdfGood = Meteor.absoluteUrl(`confirm_pdf/${paperId}/${timeStamp}/conversion_succesful`);
 const downloadUrl = sanitizedUrl;
 const options = {
   paperTitle , 
   sanitizedUrl , 
   date, 
   name,
   userId ,
   paperId ,

 }
 try {
   //update the paper with details
 return sendMailPdfUploaded( options )
 .then(Meteor.bindEnvironment(( response )=>{
  sendEmail({ from: 'Erudite Scholars <mail@eruditescholars.net>',
  to: `${firstName} ${lastName} <${to}>`,
  subject : `Confirm Pdf Copy Of ${paperTitle}`,
  template: "paper-uploaded",
  templateVars: {
        firstName,
        paperTitle,
        urlPdfGood,
        urlPdfBad
      },
  attachments: [{ path: downloadUrl }],           
})
return response;
})).catch((error)=> {
  logger.log('error' , `Exception || MethodName-paper.uploadPdfCopy : ${error}`);
  throw new Meteor.Error( '500' , `${ error }`);
});
 } catch (error) {
  throw new Meteor.Error( '500' , `${ error }`);
 }
},

'paper.saveArchivePdfCopy' : function paperMethod( paperObj ){
  check(paperObj , Object);
  const { paperId , url , name , date , teamId , others  } = paperObj;
  const sanitizedUrl = url.replace( name, `${s3PublicUrl( name )}`);
  const obj = {
    "uploadDate" : date,
    "paperUrl" : sanitizedUrl,
    "fileName" : name,
  }
  const paperUrl = sanitizedUrl ;
  const editionId = teamId;
  const journalId = others;
  const pdf = {
    paperUrl : sanitizedUrl ,
    fileName : name 
  }
  try {
    Papers.update({"_id" : paperId } , {$addToSet : {"paperUploads" : obj} , 
                                        $set : {"pdf" : pdf }});

    const paper = Papers.findOne( paperId );
    const paperDetails = {
       paperTitle : paper.title,
       abstract : paper.abstract ,
       authors : paper.authors ,
       paperType : paper.paperType ,
       links : pdf ,
       id : paperId ,
       views : 0 ,
       downloads : 0 ,
    }

    //remove the paper details before inserting the new one
    Journal.update( {"_id" : journalId , 
    "publishedEditions.editionId" : editionId } , 
    { $pull :  {"publishedEditions.$.papers" :  {"id" : paperId} }})

   return Journal.update( {"_id" : journalId , 
   "publishedEditions.editionId" : editionId } , 
   { $addToSet :  {"publishedEditions.$.papers" :  paperDetails }}); 
  } catch (error) {
    logger.log('error' , `Error || ${error}`)
  }
},

'papers.removeAuthor' : function paperMethod( id , author ){
    check(author , Object);
    check(id , String );
        //check and make sure the paper has at least an author
     const paperAuthors = Papers.findOne(id);
        if (paperAuthors.authors.length === 1){
          logger.log('info' , `A paper should have at least an author`);
          throw new Meteor.Error(500, "A paper should have at least an author");
        }
        return Papers.update(id ,{$pull : {"authors" : author }} );
    },
    'paper.insertNewPaper' : function paperMethod( paper ){
      check(paper , Object);
      try {
        return Papers.insert( paper );
      } catch (error) {
        throw new Meteor.Error(500, error );
      }
      
  },
  'paper.storePaperToAWS': function paperMethod( paper ) {
    check( paper  ,  {
      paperId : String,
      url : String,
      name : String,
      date : String,
    });
    const sanitizedUrl =
    paper.url.replace( paper.name, `${s3PublicUrl(paper.name)}`);
    //push the object into the paperupload array document;
    const uploadedPaper = {
      paperUrl : sanitizedUrl ,
      fileName : paper.name ,
      uploadDate : paper.date,
    }
          // Papers.update(paper.paperId , {$set : {"paperUploaded" : true }});
    return Papers.update({ _id : paper.paperId } , 
                         {$push : {"paperUploads" : uploadedPaper} , 
                                   $set : {"paperUploaded" : true , 
                                           "currentPaperStatus" : "01" }});
  },
  'paper.insertNewArchivePaper' : function journalMethod( options ){
    check( options , Object )
    return SaveArchivePaper ( options ).then((response) => {
      return response;
   }).catch((error)=> {
    logger.log('error' , `Exception : ${error}`)
    throw new Meteor.Error( '500' , `${ error }`)
  })
 },
 'paper.incrementDownloadCount' : function journalMethod( paperId , journalId , editionId ){
    check( paperId , String )
    check( journalId , String )
    check( editionId , String )

  
    Papers.update( paperId , {$inc : {"downloadsCount" : 1 }})
    const paper = Papers.findOne( paperId );
    const paperDetails = {
        paperTitle : paper.title,
        abstract : paper.abstract ,
        authors : paper.authors ,
        links : paper.pdf ,
        id : paperId ,
        pages : paper.pages,
        paperType : paper.paperType,
        views : paper.viewed,
        downloads : paper.downloadsCount
      }
      //find the journal and extract the editionId 
     
      //remove the paper details before inserting the new one
   Journal.update( {"_id" : journalId , 
                    "publishedEditions.editionId" : editionId } , 
         { $pull :  {"publishedEditions.$.papers" :  {"id" : paperId} }})
    
        
    return Journal.update( {"_id" : journalId , 
    "publishedEditions.editionId" : editionId } , 
    { $addToSet :  {"publishedEditions.$.papers" :  paperDetails }});


  },
  'paper.incrementViewCount' : function journalMethod( paperId , journalId , editionId ){
    
     //return Papers.update( paperId , {$inc : {"viewed" : 1 }})
     check( paperId , String )
     check( journalId , String )
     check( editionId , String )
 
   
     Papers.update( paperId , {$inc : {"viewed" : 1 }})
     const paper = Papers.findOne( paperId );
     const paperDetails = {
         paperTitle : paper.title,
         abstract : paper.abstract ,
         authors : paper.authors ,
         links : paper.pdf ,
         id : paperId ,
         pages : paper.pages,
         paperType : paper.paperType,
         views : paper.viewed,
         downloads : paper.downloadsCount
       }
 
       //find the journal and extract the editionId 
 
       //remove the paper details before inserting the new one
    Journal.update( {"_id" : journalId , 
                     "publishedEditions.editionId" : editionId } , 
          { $pull :  {"publishedEditions.$.papers" :  {"id" : paperId} }})
     
         
     return Journal.update( {"_id" : journalId , 
     "publishedEditions.editionId" : editionId } , 
     { $addToSet :  {"publishedEditions.$.papers" :  paperDetails }});
 
    },
});


   rateLimit({
     methods: [
      'papers.update',
      'papers.save',
      'papers.delete',
      'papers.storepapertoAmazon',
      'papers.removeAuthor',
      'papers.assignPaperEditor',
    ],
     limit: 5,
     timeRange: 1000,
   });
