// admin/newsroom.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0

'use strict';

const express = require('express');

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

class NewsroomAdminController extends SiteController {

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

  async start ( ) {
    const upload = this.createMulter('newsroom-admin');

    const router = express.Router();
    router.use(async (req, res, next) => {
      res.locals.currentView = 'admin';
      res.locals.adminView = 'newsroom';
      return next();
    });

    router.param('feedId', this.populateFeedId.bind(this));
    router.param('feedEntryId', this.populateFeedEntryId.bind(this));

    router.post('/resolve', upload.none(), this.postResolveFeed.bind(this));
    router.post('/:feedId', upload.none(), this.postUpdateFeed.bind(this));
    router.post('/', upload.none(), this.postCreateFeed.bind(this));

    router.get('/create', this.getFeedEditor.bind(this));
    router.get('/:feedId', this.getFeedEditor.bind(this));

    router.get('/', this.getHomeView.bind(this));

    router.delete('/:feedId', this.deleteFeed.bind(this));

    return router;
  }

  async populateFeedId (req, res, next, feedId) {
    const { feed: feedService } = this.dtp.services;
    try {
      res.locals.feed = await feedService.getById(feedId);
      if (!res.locals.feed) {
        throw new SiteError(404, 'Feed not found');
      }
      return next();
    } catch (error) {
      this.log.error('failed to populate feedId', { feedId, error });
      return next(error);
    }
  }

  async populateFeedEntryId (req, res, next, feedEntryId) {
    const { feed: feedService } = this.dtp.services;
    try {
      res.locals.feedEntry = await feedService.getEntryById(feedEntryId);
      if (!res.locals.feedEntry) {
        throw new SiteError(404, 'Feed entry not found');
      }
      return next();
    } catch (error) {
      this.log.error('failed to populate feed entry', { feedEntryId, error });
      return next(error);
    }
  }

  async postResolveFeed (req, res) {
    const { feed: feedService } = this.dtp.services;
    try {
      const feed = await feedService.load(req.body.feedUrl);
      this.log.info('request body', { body: req.body, feed });

      const displayList = this.createDisplayList('resolve-feed');
      displayList.setInputValue(`input#title`, feed.title);
      displayList.setInputValue(`input#link`, feed.link);
      displayList.setInputValue(`textarea#description`, feed.description);

      if (feed.generator) {
        displayList.setInputValue(`input[type="hidden"][name="generator"]`, feed.generator);
      }
      if (feed.language) {
        displayList.setInputValue(`input[type="hidden"][name="language"]`, feed.language);
      }
      if (feed.published) {
        displayList.setInputValue(`input[type="hidden"][name="published"]`, feed.published);
      }

      res.status(200).json({ success: true, displayList });
    } catch (error) {
      this.log.error('failed to present the Newsroom Admin home', { error });
      return res.status(error.statusCode || 500).json({
        success: false,
        message: error.message,
      });
    }
  }

  async postUpdateFeed (req, res, next) {
    const { feed: feedService } = this.dtp.services;
    try {
      await feedService.update(res.locals.feed, req.body);
      res.redirect('/admin/newsroom');
    } catch (error) {
      this.log.error('failed to update feed', { error });
      return next(error);
    }
  }

  async postCreateFeed (req, res, next) {
    const { feed: feedService } = this.dtp.services;
    try {
      res.locals.feed = await feedService.create(req.body);
      res.redirect('/admin/newsroom');
    } catch (error) {
      this.log.error('failed to create feed', { error });
      return next(error);
    }
  }

  async getFeedEditor (req, res) {
    res.render('admin/newsroom/editor');
  }

  async getHomeView (req, res, next) {
    const { feed: feedService } = this.dtp.services;
    try {
      res.locals.pagination = this.getPaginationParameters(req, 20);
      res.locals.newsroom = await feedService.getFeeds(res.locals.pagination);
      res.render('admin/newsroom/index');
    } catch (error) {
      this.log.error('failed to present the Newsroom Admin home', { error });
      return next(error);
    }
  }

  async deleteFeed (req, res) {
    const { feed: feedService } = this.dtp.services;
    try {
      await feedService.remove(res.locals.feed);

      const displayList = this.createDisplayList('delete-feed');
      displayList.navigateTo('/admin/newsroom');
  
      res.status(200).json({ success: true, displayList });
    } catch (error) {
      this.log.error('failed to remove feed', { error });
      return res.status(error.statusCode || 500).json({
        success: false,
        message: error.message,
      });
    }
  }
}

module.exports = {
  name: 'newsroomAdmin',
  slug: 'newsroom-admin',
  create: async (dtp) => { return new NewsroomAdminController(dtp); },
};