export const REQUEST_TYPE_POST = 'POST';
export const REQUEST_TYPE_GET = 'GET';
export const REQUEST_TYPE_PUT = 'PUT';
export const REQUEST_TYPE_DELETE = 'DELETE';
export const TASK_PAGE_CREATE = 'createNewPage';
export const TASK_PAGE_EDIT = 'editPage';
export const TASK_PAGE_DELETE = 'deletePage';
export const CONTENT_TYPE_JSON = 'json';
export const CONTENT_TYPE_FORM = 'x-www-form-urlencoded';
export const API_STATUS = '/api/v1/auth/status';
export const API_GET_NAV = '/api/settings/nav';
export const API_NEW_PAGE = '/api/v1/page/write/new';
export const API_EDIT_PAGE = '/api/v1/page/write';
export const API_DELETE_PAGE = '/api/v1/page/delete';
export const API_IMAGE_UPLOAD = '/api/v1/page/add-post-image';
export const API_SETTINGS_SYNC = '/api/v1/settings/sync';
export const API_UPLOAD_AVATAR = '/api/v1/settings/add-avatar';
export const API_UPLOAD_BACKGROUND = '/api/v1/settings/add-feature-background';
export const API_PUBLISH_PAGES = '/api/v1/settings/publish-pages';
export const API_NAV_SYNC = '/api/v1/settings/nav-sync';
export const API_CREATE_BACKUP = '/api/v1/backup/create';
export const API_DOWNLOAD_BACKUP = '/api/v1/backup/download';
export const API_RESTORE_BACKUP = '/api/v1/backup/restore';
export const API_INIT_RESTORE_BACKUP = '/api/v1/backup/init-restore';
export const API_SEND_MAIL = '/api/v1/mailer';
import * as DataEvent from '../com/events/DataEvent';
export default class APIUtils {
	//--------------------------
	// constructor
	//--------------------------
	constructor() {
		this.percentComplete = 0;
		this.token = null;
		//checks backend to see if user is logged in
		//and requests encrypted token for api calls
		this._request(API_STATUS).then(response => {
			if (response.type === DataEvent.API_REQUEST_GOOD) {
				this.token = response.token;
			} else {
				//don't set token
			}
		});
	}
	//--------------------------
	// public
	//--------------------------
	syncSettings(data) {
		return new Promise((resolve, reject) => {
			this._request(
				API_SETTINGS_SYNC,
				DataEvent.API_SETTINGS_WRITE,
				REQUEST_TYPE_POST,
				CONTENT_TYPE_JSON,
				data
			)
				.then(result => {
					resolve(result);
				})
				.catch(err => {
					reject(err);
				});
		});
	}
	imageUpload(type, files) {
		return new Promise((resolve, reject) => {
			let url = '';
			switch (type) {
				case 'avatar-upload':
					url = API_UPLOAD_AVATAR;
					break;
				case 'background-upload':
					url = API_UPLOAD_BACKGROUND;
					break;
				default:
					url = API_IMAGE_UPLOAD;
					break;
			}
			var imageData = new FormData();
			for (var i = 0; i < files.length; i++) {
				var file = files[i];
				// Check the file type.
				if (!file.type.match('image.*')) {
					continue;
				}
				if (type === 'avatar-upload') {
					imageData.append('avatar_upload', file, file.name);
				} else if (type === 'background-upload') {
					imageData.append('background_upload', file, file.name);
				} else {
					imageData.append('post_image', file, file.name);
				}
			}
			this._request(
				url,
				DataEvent.API_IMAGES_UPLOAD,
				REQUEST_TYPE_POST,
				CONTENT_TYPE_FORM,
				imageData
			)
				.then(r => {
					resolve(r);
				})
				.catch(err => {
					reject(err);
				});
		});
	}
	publishSite(data) {
		return new Promise((resolve, reject) => {
			this._request(
				API_PUBLISH_PAGES,
				DataEvent.API_RENDER_PAGES,
				REQUEST_TYPE_POST,
				CONTENT_TYPE_JSON,
				data
			)
				.then(result => {
					resolve(result);
				})
				.catch(err => {
					reject(err);
				});
		});
	}

	pageActions(task, data) {
		let url, event, content;
		switch (task) {
			case TASK_PAGE_CREATE:
				url = API_NEW_PAGE;
				event = DataEvent.API_PAGE_WRITE;
				content = CONTENT_TYPE_FORM;
				break;
			case TASK_PAGE_EDIT:
				url = API_EDIT_PAGE;
				event = DataEvent.API_PAGE_WRITE;
				content = CONTENT_TYPE_FORM;
				break;

			case TASK_PAGE_DELETE:
				url = API_DELETE_PAGE;
				event = DataEvent.API_PAGE_DELETE;
				content = CONTENT_TYPE_JSON;
				break;

			default:
				break;
		}

		return new Promise((resolve, reject) => {
			this._request(url, event, REQUEST_TYPE_POST, content, data)
				.then(result => {
					resolve(result);
				})
				.catch(err => {
					reject(err);
				});
		});
	}

	syncNav(data) {
		return new Promise((resolve, reject) => {
			this._request(
				API_NAV_SYNC,
				DataEvent.API_SETTINGS_WRITE,
				REQUEST_TYPE_POST,
				CONTENT_TYPE_JSON,
				data
			)
				.then(result => {
					resolve(result);
				})
				.catch(err => {
					reject(err);
				});
		});
	}
	sendMail(message) {
		return new Promise((resolve, reject) => {
			this._request(
				API_SEND_MAIL,
				DataEvent.SEND_MAIL,
				REQUEST_TYPE_POST,
				CONTENT_TYPE_JSON,
				message
			)
				.then(result => {
					resolve(result);
				})
				.catch(err => {
					reject(err);
				});
		});
	}
	handleBackup(id, files) {
		return new Promise((resolve, reject) => {
			var url, event, method, type, data;

			if (id === 'create-backup') {
				url = API_CREATE_BACKUP;
				event = DataEvent.API_BACKUP_CREATE;
				method = REQUEST_TYPE_POST;
				type = CONTENT_TYPE_JSON;
				data = { task: 'create_backup' };
			} else {
				url = API_RESTORE_BACKUP;
				event = DataEvent.API_BACKUP_RESTORE;
				method = REQUEST_TYPE_POST;
				type = CONTENT_TYPE_FORM;
				data = new FormData();
				for (var i = 0; i < files.length; i++) {
					var file = files[i];
					// Check the file type.
					if (!file.type.match('application.zip')) {
						continue;
					}
					data.append('backup_upload', file, file.name);
				}
			}
			this._request(url, event, method, type, data)
				.then(result => {
					resolve(result);
				})
				.catch(err => {
					reject(err);
				});
		});
	}
	handleInitRestore(form) {
		return new Promise((resolve, reject) => {
			var url, event, method, type, data;

			url = API_INIT_RESTORE_BACKUP;
			event = DataEvent.API_BACKUP_RESTORE;
			method = REQUEST_TYPE_POST;
			type = CONTENT_TYPE_FORM;
			data = new FormData(form);
			this._request(url, event, method, type, data)
				.then(result => {
					resolve(result);
				})
				.catch(err => {
					reject(err);
				});
		});
	}
	//--------------------------
	// private
	//--------------------------
	_request(
		requestURL,
		eventType,
		requestType = REQUEST_TYPE_GET,
		contentType = CONTENT_TYPE_JSON,
		requestData = null
	) {
		var self = this;
		return new Promise(function (resolve, reject) {
			var request = new XMLHttpRequest();
			request.upload.onprogress = self.handleLoadProgress;
			request.open(requestType, requestURL, true);
			request.onload = () => {
				if (request.status == 200) {
					let response = JSON.parse(request['response']);
					resolve(response);
				} else {
					let error = JSON.parse(request['response']);
					reject(error);
				}
			};
			if (requestType == REQUEST_TYPE_PUT || requestType == REQUEST_TYPE_POST) {
				if (
					eventType === DataEvent.API_PAGE_WRITE ||
					eventType === DataEvent.API_IMAGES_UPLOAD ||
					eventType === DataEvent.API_SETTINGS_WRITE ||
					eventType === DataEvent.API_PAGE_DELETE ||
					eventType === DataEvent.API_RENDER_PAGES ||
					eventType === DataEvent.API_BACKUP_CREATE ||
					eventType === DataEvent.API_BACKUP_RESTORE
				)
					request.setRequestHeader('x-access-token', self.token);

				switch (contentType) {
					case CONTENT_TYPE_JSON:
						request.setRequestHeader('Content-type', 'application/' + contentType);
						request.send(JSON.stringify(requestData));
						break;
					case CONTENT_TYPE_FORM:
						request.send(requestData);
						break;
				}
			} else {
				request.send();
			}
		});
	}

	//--------------------------
	// event handlers
	//--------------------------
	handleLoadProgress(e) {
		this.percentComplete = Math.ceil((e.loaded / e.total) * 100);
		//pass element to display request progress
	}
}
