import Settings, { SETTINGS_FILE } from './Settings';
import Render from './Render';
import StringUtils from '../../src/com/utils/StringUtils';
import _ from 'lodash';
import Auth from '../data/Auth';
const settings = new Settings();
const render = new Render();
const stringUtils = new StringUtils();
const moment = require('moment');
const fs = require('fs-extra');
const AdmZip = require('adm-zip');
const auth = new Auth();

export default class Utils {
	constructor() {}

	/**
	 * Retrieves single page or pages
	 * @parameter pages: payload of pages
	 */
	organizeTags(pages) {
		let tags = [];
		for (let index = 0; index < pages.length; index++) {
			const page = pages[index];
			let temp = [];
			temp = page.metadata.tags.split(',');
			for (let i = 0; i < temp.length; i++) {
				let label = temp[i].trim();
				if (!_.find(tags, { tag_name: label })) {
					tags.push({
						tag_name: label,
						slug: stringUtils.cleanString(label),
						count: 1
					});
				} else {
					_.find(tags, { tag_name: label }).count++;
				}
			}
		}
		tags = _.orderBy(tags, ['tag_name'], ['asc']);

		settings.saveTags(tags).then(() => {
			render
				.publishTags(pages)
				.then(() => {
					//console.log(response);
				})
				.catch(() => {
					//console.log(err);
				});
		});
	}
	organizeArchive(pages) {
		let years = [];
		let archive = [];
		for (let index = 0; index < pages.length; index++) {
			let page = pages[index].metadata;
			if (page.layout !== 'index') {
				let year = moment(page.created).format('YYYY');
				if (!_.find(years, { year: year })) {
					years.push({ year: year, count: 1 });
				} else {
					_.find(years, { year: year }).count++;
				}
			}
		}
		years.sort((a, b) => parseFloat(b.year) - parseFloat(a.year));
		for (let index = 0; index < years.length; index++) {
			let item = years[index];
			let sorted = [];
			let filtered = _.filter(pages, page => {
				return moment(page.metadata.created).format('YYYY') === item.year;
			});
			for (let index = 0; index < filtered.length; index++) {
				let obj = filtered[index].metadata;
				let month = moment(obj.created).format('MM');
				if (!_.find(sorted, { month: month })) {
					sorted.push({
						month: month,
						full_month: moment(obj.created).format('MMMM'),
						count: 1,
						pages: _.filter(pages, page => {
							return (
								moment(page.metadata.created).format('YYYY') === item.year &&
								moment(page.metadata.created).format('MM') === month &&
								page.metadata.deleted === false &&
								page.metadata.published === true &&
								page.metadata.layout !== 'index'
							);
						})
					});
				} else {
					_.find(sorted, { month: month }).count++;
				}
			}
			archive.push({ year: item.year, year_data: sorted });
		}
		render.publishArchive(archive);
	}
	reindexPages(pages) {
		//let byDate = _.sortBy(pages, ['created']);
	}
	moveAssets() {
		settings
			.load(SETTINGS_FILE)
			.then(settings => {
				//move css assets to public directory
				fs.copy(
					'content/themes/' + settings.global.theme + '/assets/css',
					'public/assets/css',
					function (err) {
						if (err) {
							//console.log('An error occured while copying the folder.', err);
							//return console.error(err);
						}
						//console.log('Copy completed!');
					}
				);
				//move js assets to public directory
				fs.copy(
					'content/themes/' + settings.global.theme + '/assets/scripts',
					'public/assets/scripts',
					function (err) {
						if (err) {
							//console.log('An error occured while copying the folder.', err);
							//return console.error(err);
						}
						//console.log('Copy completed!');
					}
				);
			})
			.catch(() => {
				//console.log('ERROR', err);
			});
	}
	createBackup() {
		//let self = this;
		var response;
		return new Promise(resolve => {
			var zip = new AdmZip();
			zip.addLocalFolder('public/assets/images/blog', 'public/assets/images/blog');
			zip.addLocalFolder('content/pages', 'content/pages/');
			zip.addLocalFile('site/folks.json', 'settings/');
			zip.addLocalFile('site/settings.json', 'settings/');
			zip.addLocalFile('site/tags.json', 'settings/');
			zip.writeZip('content/backup.zip');
			fs.readJSON('site/settings.json').then(settings => {
				settings.global.last_backup = moment(Date.now()).format();
				fs.writeJSON('site/settings.json', settings);
			});

			response = {
				type: '',
				message: 'BACKUP CREATED'
			};

			resolve(response);
		});
	}

	restoreBackup(file) {
		var response;
		return new Promise((resolve, reject) => {
			var zip = new AdmZip(file.buffer);
			try {
				zip.extractEntryTo('settings/settings.json', 'site', false, true);
				zip.extractEntryTo('settings/folks.json', 'site', false, true);
				zip.extractEntryTo('settings/tags.json', 'site', false, true);
				zip.getEntries().forEach(function (entry) {
					var entryName = entry.entryName;
					var list = entryName.split('/');
					if (list[0] === 'public') {
						if (list[6]) {
							zip.extractEntryTo(
								entryName,
								'public/assets/images/blog/' + list[4] + '/' + list[5],
								false,
								true
							);
						}
					}
					if (list[0] === 'content') {
						if (list[4]) {
							zip.extractEntryTo(
								entryName,
								'content/pages/' + list[2] + '/' + list[3],
								false,
								true
							);
						}
						zip.extractEntryTo('content/pages/index.md', 'content/pages', false, true);
					}
				});

				resolve();
			} catch (error) {
				response = {
					type: error,
					message: 'ERROR READING BACKUP'
				};
				reject(response);
			}
		});
	}

	verifyBackup(file, body) {
		var response;
		var zip = new AdmZip(file.buffer);
		var credentials = { handle: body.restore_member_handle, pass: body.restore_member_pass };
		var self = this;
		return new Promise((resolve, reject) => {
			try {
				let folks = JSON.parse(zip.readAsText('settings/folks.json'));
				auth.verifyCredentials(folks, credentials)
					.then(() => {
						//resolve(r);
						self.restoreBackup(file)
							.then(() => {
								response = {
									type: '',
									message: 'RESTORE COMPLETE'
								};
								resolve(response);
							})
							.catch(err => {
								response = {
									type: err,
									message: 'ERROR RESTORING BACKUP'
								};
							});
					})
					.catch(err => {
						reject(err);
					});
			} catch (error) {
				response = {
					type: 'error',
					message: 'ERROR READING BACKUP FILE'
				};

				reject(response);
			}
		});
	}
}
