import fh from 'filehound';
import fs from 'fs-extra';
import metadataParser from 'markdown-yaml-metadata-parser';
import _ from 'lodash';
import * as DataEvent from '../../src/com/events/DataEvent';
import Navigation from './Navigation';
import Utils from './Utils';
const moment = require('moment');
const nav = new Navigation();
const utils = new Utils();

/**
 *  Class for handling blog content pages
 */

export default class Book {
	//--------------------------
	// constructor
	//--------------------------
	constructor() {}
	//--------------------------
	// methods
	//--------------------------
	start() {}
	/**
	 * Retrieves single page or pages
	 * @parameter id: optional id if requesting a single Page
	 */
	getPage(id) {
		return new Promise((resolve, reject) => {
			fh.create()
				.paths('content/pages')
				.ext('md')
				.find()
				.then(files => {
					let pages = [];
					for (let index = 0; index < files.length; index++) {
						fs.readFile(files[index], { encoding: 'utf8' }, (err, file) => {
							pages.push(metadataParser(file));
						});
					}
					if (id === null || id === null || id === undefined) {
						setTimeout(() => {
							//TODO: Duct tape solution until something better created
							utils.organizeTags(pages);
							utils.organizeArchive(pages);
							resolve(pages);
						}, 100);
					} else {
						setTimeout(() => {
							//TODO: Duct tape solution until something better created

							//make check against menu to see if page should be marked as menu item
							//if it doesnt' exist in menu change, edit page to
							let page = _.find(pages, list => {
								return list.metadata.uuid === id;
							});
							resolve(page);
						}, 100);
					}
				})
				.catch(err => {
					reject(err);
				});
		});
	}
	/**
	 * Edits single page based on id and task
	 * @parameter body: object that contains all page information
	 * @parameter id: identifier for page being edited
	 * @parameter task: type of task being performed - listed in DataEvents Class /src/com/events
	 * @parameter user: object contain user information
	 */
	editPage(body, id, task, user) {
		return new Promise((resolve, reject) => {
			let self = this;
			let response = [];
			switch (task) {
				case DataEvent.API_PAGE_CREATE:
				case DataEvent.API_PAGE_WRITE:
					var layout = 'page';
					var path = '';
					fs.ensureDir(
						'content/pages/' +
							moment(body.created).format('YYYY') +
							'/' +
							moment(body.created).format('MM') +
							'/'
					).then(() => {
						if (body.menu === 'true') {
							body.path =
								moment(body.created).format('YYYY') +
								'/' +
								moment(body.created).format('MM');
							nav.editMenu(DataEvent.MENU_ADD_ITEM, body, user);
						} else {
							nav.editMenu(DataEvent.MENU_DELETE_ITEM, body, user);
						}
						if (body.layout !== 'page') layout = body.layout;
						if (body.layout === null || body.layout === 'null') layout = 'page';
						var pageWrite =
							'---\n' +
							'id: ' +
							body.id +
							'\n' +
							'uuid: ' +
							body.uuid +
							'\n' +
							'title: ' +
							body.title +
							'\n' +
							'feature: ' +
							body.feature +
							'\n' +
							'path: ' +
							moment(body.created).format('YYYY') +
							'/' +
							moment(body.created).format('MM') +
							'\n' +
							'layout: ' +
							layout +
							'\n' +
							'tags: ' +
							body.tags +
							'\n' +
							'author: ' +
							user.handle +
							'\n' +
							'created: ' +
							moment(body.created).format() +
							'\n' +
							'updated: ' +
							moment(Date.now()).format() +
							'\n' +
							'deleted: ' +
							body.deleted +
							'\n' +
							'menu: ' +
							body.menu +
							'\n' +
							'featured: ' +
							body.featured +
							'\n' +
							'published: ' +
							body.published +
							'\n' +
							'slug: ' +
							body.slug +
							'\n' +
							'---\n' +
							body.content;
						layout === 'index'
							? (path = 'content/pages/index.md')
							: (path =
									'content/pages/' +
									moment(body.created).format('YYYY') +
									'/' +
									moment(body.created).format('MM') +
									'/' +
									body.slug +
									'.md');
						fs.writeFile(path, pageWrite, err => {
							// throws an error, you could also catch it here

							if (err) {
								response = { type: DataEvent.PAGE_ERROR, message: err };
								reject(response);
							}

							// success case, the file was saved
							if (task === DataEvent.API_PAGE_CREATE) {
								// if new file, update settings index and page count
								response = {
									type: DataEvent.PAGE_ADDED,
									message: 'New Page Created',
									id: body.uuid
								};
								resolve(response);
							} else {
								response = {
									type: DataEvent.PAGE_UPDATED,
									message: 'Page saved. Nice Work'
								};
								resolve(response);
							}
						});
					});

					break;
				case DataEvent.API_PAGE_DELETE:
					this.getPage(id)
						.then(page => {
							let body = _.mapValues(page.metadata);

							body.content = page.content;
							body.deleted = moment(Date.now()).format();
							body.menu = false;

							self.editPage(body, body.uuid, DataEvent.API_PAGE_WRITE, user)
								.then(() => {
									let item = {
										title: body.title,
										id: body.id,
										slug: body.slug,
										uuid: body.uuid
									};
									nav.editMenu(DataEvent.MENU_DELETE_ITEM, item);

									response = {
										type: DataEvent.PAGE_DELETED,
										message: 'Page deleted, sport',
										data: { uuid: body.uuid }
									};
									resolve(response);
								})
								.catch(err => {
									response = { type: DataEvent.PAGE_ERROR, message: err };
									reject(response);
								});
						})
						.catch(err => {
							response = { type: DataEvent.PAGE_ERROR, message: err };
							reject(response);
						});
					break;
			}
		});
	}

	//--------------------------
	// event handlers
	//--------------------------
}
