// post.js
// Copyright (C) 2021 Digital Telepresence, LLC
// License: Apache-2.0

'use strict';

const express = require('express');
// const multer = require('multer');

const { SiteController, SiteError } = require('../../lib/site-lib');

class AuthorController extends SiteController {

  constructor (dtp) {
    super(dtp, module.exports);
  }

  async start ( ) {
    const { dtp } = this;
    const { limiter: limiterService } = dtp.services;
    const { author: authorLimiter } = limiterService.config;

    async function checkAuthorPublisherPermissions(req, res, next) {

      if (!req.user) {
        return res.redirect(302, '/welcome');
      }
      
      if (req.user.flags.isAdmin) {
        return next();
      }
      
      const canAuthor = req.user.permissions.canAuthorPosts;
      const canPublish = req.user.permissions.canPublishPosts;
      
      if (!canAuthor && !canPublish) {
          return next(new SiteError(403, 'Author privileges are required'));
      }
      return next();
    }
      
    async function checkPermissions (req, res, next)  {
      res.locals.currentView = 'author';
      const canAuthorOrPublish = await checkAuthorPublisherPermissions(req, res, next);
      return canAuthorOrPublish;
    }

    const router = express.Router();
    dtp.app.use('/author', router);
    
    router.use(checkPermissions);

    router.get('/posts',
      limiterService.createMiddleware(authorLimiter.getPostIndex),
      this.getPublishedPostHome.bind(this),
    );

    router.get('/drafts',
      limiterService.createMiddleware(authorLimiter.getPostIndex),
      this.getDraftsHome.bind(this),
    );

    router.get('/',
      limiterService.createMiddleware(authorLimiter.getIndex),
      this.getAuthorHome.bind(this),
    );
  }

  async getPublishedPostHome (req, res, next) {
    const { post: postService } = this.dtp.services;
    try {
      const isAdmin = req.user.flags.isAdmin;
      const canAuthor = req.user.permissions.canAuthorPosts;
      const canPublish = req.user.permissions.canPublishPosts;
      res.locals.pagination = this.getPaginationParameters(req, 20);
      
      if(canAuthor) {
        
        if ( canPublish ) {
          
          res.locals.published = await postService.getPosts( { skip: 0, cpp: 5 }, ['published'], true );
          
          res.locals.allPosts = true;
          
          res.locals.published.all = true;
        
        } else {
          
          res.locals.published = await postService.getForAuthor( req.user, ['published'], { skip: 0, cpp: 5 } );

        }
      } 
      else if ( canPublish || isAdmin ) {
        res.locals.published = await postService.getPosts( { skip: 0, cpp: 5 }, ['published'], true );
        res.locals.published.all = true;
      }

      res.render('author/post/index');
    } catch (error) {
      this.log.error('failed to render Author dashboard', { error });
      return next(error);
    }
  }

  async getDraftsHome (req, res, next) {
    const { post: postService } = this.dtp.services;
    try {
      const isAdmin = req.user.flags.isAdmin;
      const canAuthor = req.user.permissions.canAuthorPosts;
      const canPublish = req.user.permissions.canPublishPosts;
      res.locals.pagination = this.getPaginationParameters(req, 20);
      const status = ['draft'];

      if(canAuthor) {
        
        if ( canPublish ) {
          
          res.locals.drafts = await postService.getPosts( { skip: 0, cpp: 5 }, status, true );
          
          res.locals.allPosts = true;
          
          res.locals.drafts.all = true;
        
        } else {
          
          res.locals.drafts = await postService.getForAuthor( req.user, status, { skip: 0, cpp: 5 } );

        }
      } 
      else if ( canPublish || isAdmin ) {
        res.locals.drafts = await postService.getPosts( { skip: 0, cpp: 5 }, status, true );
        res.locals.drafts.all = true;
      }

      res.render('author/draft/index');
    } catch (error) {
      this.log.error('failed to render Author dashboard', { error });
      return next(error);
    }
  }

  async getAuthorHome (req, res, next) {
    const { /*comment: commentService,*/ post: postService } = this.dtp.services;
    try {

      const isAdmin = req.user.flags.isAdmin;
      const canAuthor = req.user.permissions.canAuthorPosts;
      const canPublish = req.user.permissions.canPublishPosts;
      
      if(canAuthor || isAdmin) {
        
        if(canPublish || isAdmin) {
          
          res.locals.published = await postService.getPosts({ skip: 0, cpp: 5 });
          res.locals.drafts = await postService.getPosts({ skip: 0, cpp: 5 }, ['draft']);
          
          res.locals.authorComments = await postService.getCommentsForAuthor(req.user, res.locals.pagination);
          res.locals.pagination = this.getPaginationParameters(req, 20);
          res.locals.published.all = true;
          res.locals.drafts.all = true;
        } else {
          res.locals.drafts = await postService.getForAuthor(req.user, ['draft'], { skip: 0, cpp: 5 });
          res.locals.published = await postService.getForAuthor(req.user, ['published'], { skip: 0, cpp: 5 });
          
          res.locals.pagination = this.getPaginationParameters(req, 20);
          res.locals.authorComments = await postService.getCommentsForAuthor(req.user, res.locals.pagination);
        }
      }
      else if (canPublish) {
        res.locals.posts = await postService.getPosts({ skip: 0, cpp: 5 }, ['draft', 'published', 'archived']);
        res.locals.posts.all = true;
      }
      res.locals.pageTitle = `Author Dashboard for ${req.user.username}`;
      res.render('author/index');
    } catch (error) {
      this.log.error('failed to render Author dashboard', { error });
      return next(error);
    }
  }
}

module.exports = {
  slug: 'author',
  name: 'author',
  create: async (dtp) => {
    let controller = new AuthorController(dtp);
    return controller;
  },
};