import * as DataEvent from '../../../src/com/events/DataEvent';
import mdparser from 'markdown-yaml-metadata-parser';
const uuidv4 = require('uuid/v4');
const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const fs = require('fs-extra');
const _ = require('lodash');
const crypto = require('crypto'); // for setting up new accounts
const secret_key = '58d5aeec3c604e2837aef70bc1606f35131ab8fea9731925558f5acfaa00da60';
const moment = require('moment');

/**
 * Get Auth Status
 */
router.get('/', function (req, res) {
	var token = req.headers['x-access-token'];
	if (!token) return res.status(401).send({ auth: false, message: 'No token provided.' });

	jwt.verify(token, 'super-secret-string', function (err, decoded) {
		if (err)
			return res.status(500).send({ auth: false, message: 'Failed to authenticate token.' });
		res.status(200).send(decoded);
	});
});

/**
 * Get Auth Status
 */
router.get('/status', function (req, res) {
	if (req.session.user) {
		let session = req.session;
		res.json({
			type: DataEvent.API_REQUEST_GOOD,
			message: 'Auth is Good',
			token: session.hashToken
		});
	} else {
		res.json({
			type: DataEvent.API_REQUEST_LAME,
			message: 'NOT AUTHORIZED'
		});
	}
});
/**
 * Login Member and return token
 */
router.post('/login', function (req, res) {
	fs.readJson('site/folks.json').then(folks => {
		let found = _.find(folks, { handle: req.body.handle });
		if (found) {
			if (!isValidPassword(found, req.body.password)) {
				res.json({
					type: DataEvent.REQUEST_LAME,
					message: 'CHECK YOUR PASSWORD'
				});
			}

			let token = jwt.sign({ id: found.id }, found.key, {
				expiresIn: 86400 // expires in 24 hours
			});

			let session = req.session;
			session.user = found;
			session.token = token;
			session.hashToken = hashToken(token);
			res.json({
				type: DataEvent.REQUEST_GOOD,
				message: 'Welcome Back',
				token: session.hashToken
			});
		} else {
			res.json({
				type: DataEvent.REQUEST_LAME,
				message: 'Need to see some id, champ.'
			});
		}
	});
});

/**
 * Initial Site Setup
 */
router.post('/init', function (req, res) {
	let body = req.body;
	let re = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	// check email
	if (!re.test(body.new_member_email)) {
		res.json({
			type: DataEvent.API_INIT_LAME,
			message: 'Need a valid email address'
		});
	}
	//check handle is being passed
	if (body.new_member_handle === null || body.new_member_handle === '') {
		res.json({
			type: DataEvent.API_INIT_LAME,
			message: 'No handle. Kinda need that.'
		});
	}
	// check password match
	if (
		body.new_member_pass !== body.new_member_pass2 ||
		body.new_member_pass === '' ||
		body.new_member_pass2 === ''
	) {
		res.json({
			type: DataEvent.API_INIT_LAME,
			message: 'Passwords do not match.'
		});
	}

	if (body.new_member_title === null || body.new_member_title === '') {
		res.json({
			type: DataEvent.API_INIT_LAME,
			message: 'No title. Gotta call it something.'
		});
	}

	let key = crypto
		.createHash('sha256')
		.update(body.new_member_pass + secret_key)
		.digest('hex');

	// set up config files
	fs.readJson('site/init/settings-template.json').then(fresh => {
		fresh.global.title = body.new_member_title;
		fs.writeJSON('site/settings.json', fresh);
	});

	fs.readJson('site/init/folks-template.json').then(folks => {
		folks[0].id = 1;
		folks[0].handle = body.new_member_handle;
		folks[0].email = body.new_member_email;
		folks[0].password = bcrypt.hashSync(body.new_member_pass, bcrypt.genSaltSync(10), null);
		folks[0].key = key;
		folks[0].role = 'hnic';
		folks[0].created = moment(Date.now()).format();
		folks[0].updated = moment(Date.now()).format();
		fs.writeJSON('site/folks.json', folks);
	});

	fs.writeJson('site/tags.json', { tags: [] });

	//set up index file as first page

	fs.readFile('site/init/index-template.md', { encoding: 'utf8' }).then(file => {
		let index = mdparser(file);
		let data = index.metadata;
		data.uuid = uuidv4();
		data.path = moment().format('YYYY') + '/' + moment().format('MM');
		data.author = body.new_member_handle;
		data.created = moment(Date.now()).format();
		data.updated = moment(Date.now()).format();

		var init =
			'---\n' +
			'id: ' +
			data.id +
			'\n' +
			'uuid: ' +
			data.uuid +
			'\n' +
			'title: ' +
			data.title +
			'\n' +
			'feature: ' +
			data.feature +
			'\n' +
			'path: ' +
			moment(Date.now()).format('YYYY') +
			'/' +
			moment(Date.now()).format('MM') +
			'\n' +
			'layout: ' +
			'index' +
			'\n' +
			'tags: ' +
			data.tags +
			'\n' +
			'author: ' +
			body.new_member_handle +
			'\n' +
			'created: ' +
			moment(Date.now()).format() +
			'\n' +
			'updated: ' +
			moment(Date.now()).format() +
			'\n' +
			'deleted: ' +
			'false' +
			'\n' +
			'menu: ' +
			data.menu +
			'\n' +
			'featured: ' +
			data.featured +
			'\n' +
			'published: ' +
			data.published +
			'\n' +
			'slug: ' +
			data.slug +
			'\n' +
			'---\n' +
			index.content;

		fs.ensureDir('content/pages/').then(() => {
			fs.writeFile('content/pages/index.md', init)
				.then(() => {
					//console.log('index file created');
				})
				.catch(() => {
					//console.log('ERROR', err);
				});
		});
	});

	res.json({
		type: DataEvent.API_INIT_GOOD,
		message: 'All Set Up'
	});
});

//router.post('/logout', function(req, res) {});
module.exports = router;

function isValidPassword(user, password) {
	return bcrypt.compareSync(password, user.password);
}

function hashToken(token) {
	return bcrypt.hashSync(token, bcrypt.genSaltSync(10), null);
}
